Merge llvm-project release/15.x llvmorg-15.0.0-rc2-40-gfbd2950d8d0d
This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp to llvmorg-15.0.0-rc2-40-gfbd2950d8d0d. PR: 265425 MFC after: 2 weeks
This commit is contained in:
commit
61cfbce334
@ -3287,8 +3287,12 @@ class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
|
||||
return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
|
||||
}
|
||||
|
||||
ConceptDecl *getCanonicalDecl() override { return getFirstDecl(); }
|
||||
const ConceptDecl *getCanonicalDecl() const { return getFirstDecl(); }
|
||||
ConceptDecl *getCanonicalDecl() override {
|
||||
return cast<ConceptDecl>(getPrimaryMergedDecl(this));
|
||||
}
|
||||
const ConceptDecl *getCanonicalDecl() const {
|
||||
return const_cast<ConceptDecl *>(this)->getCanonicalDecl();
|
||||
}
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
|
@ -525,6 +525,11 @@ class Module {
|
||||
Parent->SubModules.push_back(this);
|
||||
}
|
||||
|
||||
/// Is this module have similar semantics as headers.
|
||||
bool isHeaderLikeModule() const {
|
||||
return isModuleMapModule() || isHeaderUnit();
|
||||
}
|
||||
|
||||
/// Is this a module partition.
|
||||
bool isModulePartition() const {
|
||||
return Kind == ModulePartitionInterface ||
|
||||
|
@ -4479,6 +4479,8 @@ class Sema final {
|
||||
bool CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old);
|
||||
bool CheckRedeclarationExported(NamedDecl *New, NamedDecl *Old);
|
||||
bool CheckRedeclarationInModule(NamedDecl *New, NamedDecl *Old);
|
||||
bool IsRedefinitionInModule(const NamedDecl *New,
|
||||
const NamedDecl *Old) const;
|
||||
|
||||
void DiagnoseAmbiguousLookup(LookupResult &Result);
|
||||
//@}
|
||||
|
@ -1738,7 +1738,8 @@ class ASTReader
|
||||
const LangOptions &LangOpts,
|
||||
const TargetOptions &TargetOpts,
|
||||
const PreprocessorOptions &PPOpts,
|
||||
StringRef ExistingModuleCachePath);
|
||||
StringRef ExistingModuleCachePath,
|
||||
bool RequireStrictOptionMatches = false);
|
||||
|
||||
/// Returns the suggested contents of the predefines buffer,
|
||||
/// which contains a (typically-empty) subset of the predefines
|
||||
|
@ -637,10 +637,10 @@ static bool TryPrintAsStringLiteral(raw_ostream &Out,
|
||||
return false;
|
||||
|
||||
// Nothing we can do about a sequence that is not null-terminated
|
||||
if (!Inits.back().getInt().isZero())
|
||||
if (!Inits.back().isInt() || !Inits.back().getInt().isZero())
|
||||
return false;
|
||||
else
|
||||
Inits = Inits.drop_back();
|
||||
|
||||
Inits = Inits.drop_back();
|
||||
|
||||
llvm::SmallString<40> Buf;
|
||||
Buf.push_back('"');
|
||||
@ -655,6 +655,8 @@ static bool TryPrintAsStringLiteral(raw_ostream &Out,
|
||||
}
|
||||
|
||||
for (auto &Val : Inits) {
|
||||
if (!Val.isInt())
|
||||
return false;
|
||||
int64_t Char64 = Val.getInt().getExtValue();
|
||||
if (!isASCII(Char64))
|
||||
return false; // Bye bye, see you in integers.
|
||||
|
@ -358,6 +358,8 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
|
||||
|
||||
HasFloat16 = SSELevel >= SSE2;
|
||||
|
||||
HasBFloat16 = SSELevel >= SSE2;
|
||||
|
||||
MMX3DNowEnum ThreeDNowLevel = llvm::StringSwitch<MMX3DNowEnum>(Feature)
|
||||
.Case("+3dnowa", AMD3DNowAthlon)
|
||||
.Case("+3dnow", AMD3DNow)
|
||||
|
@ -156,6 +156,8 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
|
||||
public:
|
||||
X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
|
||||
: TargetInfo(Triple) {
|
||||
BFloat16Width = BFloat16Align = 16;
|
||||
BFloat16Format = &llvm::APFloat::BFloat();
|
||||
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
|
||||
AddrSpaceMap = &X86AddrSpaceMap;
|
||||
HasStrictFP = true;
|
||||
@ -400,6 +402,8 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
|
||||
uint64_t getPointerAlignV(unsigned AddrSpace) const override {
|
||||
return getPointerWidthV(AddrSpace);
|
||||
}
|
||||
|
||||
const char *getBFloat16Mangling() const override { return "u6__bf16"; };
|
||||
};
|
||||
|
||||
// X86-32 generic target
|
||||
|
@ -649,8 +649,8 @@ void CodeGenModule::EmitCXXModuleInitFunc(Module *Primary) {
|
||||
|
||||
SmallVector<llvm::Function *, 8> ModuleInits;
|
||||
for (Module *M : AllImports) {
|
||||
// No Itanium initializer in module map modules.
|
||||
if (M->isModuleMapModule())
|
||||
// No Itanium initializer in header like modules.
|
||||
if (M->isHeaderLikeModule())
|
||||
continue; // TODO: warn of mixed use of module map modules and C++20?
|
||||
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
|
||||
SmallString<256> FnName;
|
||||
@ -778,8 +778,8 @@ CodeGenModule::EmitCXXGlobalInitFunc() {
|
||||
SmallVector<llvm::Function *, 8> ModuleInits;
|
||||
if (CXX20ModuleInits)
|
||||
for (Module *M : ImportedModules) {
|
||||
// No Itanium initializer in module map modules.
|
||||
if (M->isModuleMapModule())
|
||||
// No Itanium initializer in header like modules.
|
||||
if (M->isHeaderLikeModule())
|
||||
continue;
|
||||
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
|
||||
SmallString<256> FnName;
|
||||
|
@ -2343,6 +2343,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
|
||||
std::vector<llvm::Type *> ArgElemTypes;
|
||||
std::vector<llvm::Value*> Args;
|
||||
llvm::BitVector ResultTypeRequiresCast;
|
||||
llvm::BitVector ResultRegIsFlagReg;
|
||||
|
||||
// Keep track of inout constraints.
|
||||
std::string InOutConstraints;
|
||||
@ -2400,6 +2401,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
|
||||
ResultRegQualTys.push_back(QTy);
|
||||
ResultRegDests.push_back(Dest);
|
||||
|
||||
bool IsFlagReg = llvm::StringRef(OutputConstraint).startswith("{@cc");
|
||||
ResultRegIsFlagReg.push_back(IsFlagReg);
|
||||
|
||||
llvm::Type *Ty = ConvertTypeForMem(QTy);
|
||||
const bool RequiresCast = Info.allowsRegister() &&
|
||||
(getTargetHooks().isScalarizableAsmOperand(*this, Ty) ||
|
||||
@ -2717,10 +2721,21 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
|
||||
// ResultRegDests can be also populated by addReturnRegisterOutputs() above,
|
||||
// in which case its size may grow.
|
||||
assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
|
||||
assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
|
||||
for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
|
||||
llvm::Value *Tmp = RegResults[i];
|
||||
llvm::Type *TruncTy = ResultTruncRegTypes[i];
|
||||
|
||||
if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
|
||||
// Target must guarantee the Value `Tmp` here is lowered to a boolean
|
||||
// value.
|
||||
llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
|
||||
llvm::Value *IsBooleanValue =
|
||||
Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
|
||||
llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
|
||||
Builder.CreateCall(FnAssume, IsBooleanValue);
|
||||
}
|
||||
|
||||
// If the result type of the LLVM IR asm doesn't match the result type of
|
||||
// the expression, do the conversion.
|
||||
if (ResultRegTypes[i] != ResultTruncRegTypes[i]) {
|
||||
|
@ -521,7 +521,7 @@ static void setVisibilityFromDLLStorageClass(const clang::LangOptions &LO,
|
||||
|
||||
void CodeGenModule::Release() {
|
||||
Module *Primary = getContext().getModuleForCodeGen();
|
||||
if (CXX20ModuleInits && Primary && !Primary->isModuleMapModule())
|
||||
if (CXX20ModuleInits && Primary && !Primary->isHeaderLikeModule())
|
||||
EmitModuleInitializers(Primary);
|
||||
EmitDeferred();
|
||||
DeferredDecls.insert(EmittedDeferredDecls.begin(),
|
||||
@ -2521,21 +2521,23 @@ void CodeGenModule::EmitModuleInitializers(clang::Module *Primary) {
|
||||
// source, first Global Module Fragments, if present.
|
||||
if (auto GMF = Primary->getGlobalModuleFragment()) {
|
||||
for (Decl *D : getContext().getModuleInitializers(GMF)) {
|
||||
assert(D->getKind() == Decl::Var && "GMF initializer decl is not a var?");
|
||||
if (isa<ImportDecl>(D))
|
||||
continue;
|
||||
assert(isa<VarDecl>(D) && "GMF initializer decl is not a var?");
|
||||
EmitTopLevelDecl(D);
|
||||
}
|
||||
}
|
||||
// Second any associated with the module, itself.
|
||||
for (Decl *D : getContext().getModuleInitializers(Primary)) {
|
||||
// Skip import decls, the inits for those are called explicitly.
|
||||
if (D->getKind() == Decl::Import)
|
||||
if (isa<ImportDecl>(D))
|
||||
continue;
|
||||
EmitTopLevelDecl(D);
|
||||
}
|
||||
// Third any associated with the Privat eMOdule Fragment, if present.
|
||||
if (auto PMF = Primary->getPrivateModuleFragment()) {
|
||||
for (Decl *D : getContext().getModuleInitializers(PMF)) {
|
||||
assert(D->getKind() == Decl::Var && "PMF initializer decl is not a var?");
|
||||
assert(isa<VarDecl>(D) && "PMF initializer decl is not a var?");
|
||||
EmitTopLevelDecl(D);
|
||||
}
|
||||
}
|
||||
|
@ -2871,7 +2871,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo,
|
||||
} else if (k >= BuiltinType::Bool && k <= BuiltinType::LongLong) {
|
||||
Current = Integer;
|
||||
} else if (k == BuiltinType::Float || k == BuiltinType::Double ||
|
||||
k == BuiltinType::Float16) {
|
||||
k == BuiltinType::Float16 || k == BuiltinType::BFloat16) {
|
||||
Current = SSE;
|
||||
} else if (k == BuiltinType::LongDouble) {
|
||||
const llvm::fltSemantics *LDF = &getTarget().getLongDoubleFormat();
|
||||
@ -3002,7 +3002,8 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo,
|
||||
Current = Integer;
|
||||
else if (Size <= 128)
|
||||
Lo = Hi = Integer;
|
||||
} else if (ET->isFloat16Type() || ET == getContext().FloatTy) {
|
||||
} else if (ET->isFloat16Type() || ET == getContext().FloatTy ||
|
||||
ET->isBFloat16Type()) {
|
||||
Current = SSE;
|
||||
} else if (ET == getContext().DoubleTy) {
|
||||
Lo = Hi = SSE;
|
||||
@ -3474,9 +3475,9 @@ GetSSETypeAtOffset(llvm::Type *IRType, unsigned IROffset,
|
||||
if (SourceSize > T0Size)
|
||||
T1 = getFPTypeAtOffset(IRType, IROffset + T0Size, TD);
|
||||
if (T1 == nullptr) {
|
||||
// Check if IRType is a half + float. float type will be in IROffset+4 due
|
||||
// Check if IRType is a half/bfloat + float. float type will be in IROffset+4 due
|
||||
// to its alignment.
|
||||
if (T0->isHalfTy() && SourceSize > 4)
|
||||
if (T0->is16bitFPTy() && SourceSize > 4)
|
||||
T1 = getFPTypeAtOffset(IRType, IROffset + 4, TD);
|
||||
// If we can't get a second FP type, return a simple half or float.
|
||||
// avx512fp16-abi.c:pr51813_2 shows it works to return float for
|
||||
@ -3488,7 +3489,7 @@ GetSSETypeAtOffset(llvm::Type *IRType, unsigned IROffset,
|
||||
if (T0->isFloatTy() && T1->isFloatTy())
|
||||
return llvm::FixedVectorType::get(T0, 2);
|
||||
|
||||
if (T0->isHalfTy() && T1->isHalfTy()) {
|
||||
if (T0->is16bitFPTy() && T1->is16bitFPTy()) {
|
||||
llvm::Type *T2 = nullptr;
|
||||
if (SourceSize > 4)
|
||||
T2 = getFPTypeAtOffset(IRType, IROffset + 4, TD);
|
||||
@ -3497,7 +3498,7 @@ GetSSETypeAtOffset(llvm::Type *IRType, unsigned IROffset,
|
||||
return llvm::FixedVectorType::get(T0, 4);
|
||||
}
|
||||
|
||||
if (T0->isHalfTy() || T1->isHalfTy())
|
||||
if (T0->is16bitFPTy() || T1->is16bitFPTy())
|
||||
return llvm::FixedVectorType::get(llvm::Type::getHalfTy(getVMContext()), 4);
|
||||
|
||||
return llvm::Type::getDoubleTy(getVMContext());
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "clang/Driver/Options.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Option/ArgList.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
|
||||
using namespace clang::driver;
|
||||
using namespace clang::driver::tools;
|
||||
@ -113,6 +114,30 @@ sparc::FloatABI sparc::getSparcFloatABI(const Driver &D,
|
||||
return ABI;
|
||||
}
|
||||
|
||||
std::string sparc::getSparcTargetCPU(const Driver &D, const ArgList &Args,
|
||||
const llvm::Triple &Triple) {
|
||||
if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
|
||||
D.Diag(diag::err_drv_unsupported_opt_for_target)
|
||||
<< A->getSpelling() << Triple.getTriple();
|
||||
return "";
|
||||
}
|
||||
|
||||
if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) {
|
||||
StringRef CPUName = A->getValue();
|
||||
if (CPUName == "native") {
|
||||
std::string CPU = std::string(llvm::sys::getHostCPUName());
|
||||
if (!CPU.empty() && CPU != "generic")
|
||||
return CPU;
|
||||
return "";
|
||||
}
|
||||
return std::string(CPUName);
|
||||
}
|
||||
|
||||
if (Triple.getArch() == llvm::Triple::sparc && Triple.isOSSolaris())
|
||||
return "v9";
|
||||
return "";
|
||||
}
|
||||
|
||||
void sparc::getSparcTargetFeatures(const Driver &D, const ArgList &Args,
|
||||
std::vector<StringRef> &Features) {
|
||||
sparc::FloatABI FloatABI = sparc::getSparcFloatABI(D, Args);
|
||||
|
@ -28,6 +28,9 @@ enum class FloatABI {
|
||||
|
||||
FloatABI getSparcFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
|
||||
|
||||
std::string getSparcTargetCPU(const Driver &D, const llvm::opt::ArgList &Args,
|
||||
const llvm::Triple &Triple);
|
||||
|
||||
void getSparcTargetFeatures(const Driver &D, const llvm::opt::ArgList &Args,
|
||||
std::vector<llvm::StringRef> &Features);
|
||||
const char *getSparcAsmModeForCPU(llvm::StringRef Name,
|
||||
|
@ -2205,6 +2205,18 @@ void Clang::AddSparcTargetArgs(const ArgList &Args,
|
||||
CmdArgs.push_back("-mfloat-abi");
|
||||
CmdArgs.push_back("hard");
|
||||
}
|
||||
|
||||
if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)) {
|
||||
StringRef Name = A->getValue();
|
||||
std::string TuneCPU;
|
||||
if (Name == "native")
|
||||
TuneCPU = std::string(llvm::sys::getHostCPUName());
|
||||
else
|
||||
TuneCPU = std::string(Name);
|
||||
|
||||
CmdArgs.push_back("-tune-cpu");
|
||||
CmdArgs.push_back(Args.MakeArgString(TuneCPU));
|
||||
}
|
||||
}
|
||||
|
||||
void Clang::AddSystemZTargetArgs(const ArgList &Args,
|
||||
@ -4610,8 +4622,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
TC.addClangWarningOptions(CmdArgs);
|
||||
|
||||
// FIXME: Subclass ToolChain for SPIR and move this to addClangWarningOptions.
|
||||
if (Triple.isSPIR() || Triple.isSPIRV())
|
||||
if (Triple.isSPIR() || Triple.isSPIRV()) {
|
||||
CmdArgs.push_back("-Wspir-compat");
|
||||
// SPIR-V support still needs pointer types in some cases as recovering
|
||||
// type from pointer uses is not always possible e.g. for extern functions
|
||||
// (see PR56660).
|
||||
CmdArgs.push_back("-no-opaque-pointers");
|
||||
}
|
||||
|
||||
// Select the appropriate action.
|
||||
RewriteKind rewriteKind = RK_None;
|
||||
@ -6576,7 +6593,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
// support by default, or just assume that all languages do.
|
||||
bool HaveModules =
|
||||
Std && (Std->containsValue("c++2a") || Std->containsValue("c++20") ||
|
||||
Std->containsValue("c++latest"));
|
||||
Std->containsValue("c++2b") || Std->containsValue("c++latest"));
|
||||
RenderModulesOptions(C, D, Args, Input, Output, CmdArgs, HaveModules);
|
||||
|
||||
if (Args.hasFlag(options::OPT_fpch_validate_input_files_content,
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "Arch/M68k.h"
|
||||
#include "Arch/Mips.h"
|
||||
#include "Arch/PPC.h"
|
||||
#include "Arch/Sparc.h"
|
||||
#include "Arch/SystemZ.h"
|
||||
#include "Arch/VE.h"
|
||||
#include "Arch/X86.h"
|
||||
@ -431,14 +432,14 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args,
|
||||
|
||||
case llvm::Triple::bpfel:
|
||||
case llvm::Triple::bpfeb:
|
||||
if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
|
||||
return A->getValue();
|
||||
return "";
|
||||
|
||||
case llvm::Triple::sparc:
|
||||
case llvm::Triple::sparcel:
|
||||
case llvm::Triple::sparcv9:
|
||||
if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
|
||||
return A->getValue();
|
||||
if (T.getArch() == llvm::Triple::sparc && T.isOSSolaris())
|
||||
return "v9";
|
||||
return "";
|
||||
return sparc::getSparcTargetCPU(D, Args, T);
|
||||
|
||||
case llvm::Triple::x86:
|
||||
case llvm::Triple::x86_64:
|
||||
|
@ -631,6 +631,16 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
|
||||
AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
|
||||
|
||||
// LLVM support for atomics on 32-bit SPARC V8+ is incomplete, so
|
||||
// forcibly link with libatomic as a workaround.
|
||||
// TODO: Issue #41880 and D118021.
|
||||
if (getToolChain().getTriple().getArch() == llvm::Triple::sparc) {
|
||||
CmdArgs.push_back("--push-state");
|
||||
CmdArgs.push_back("--as-needed");
|
||||
CmdArgs.push_back("-latomic");
|
||||
CmdArgs.push_back("--pop-state");
|
||||
}
|
||||
|
||||
if (WantPthread && !isAndroid)
|
||||
CmdArgs.push_back("-lpthread");
|
||||
|
||||
|
@ -772,7 +772,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
|
||||
if (ASTReader::isAcceptableASTFile(
|
||||
Dir->path(), FileMgr, CI.getPCHContainerReader(),
|
||||
CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(),
|
||||
SpecificModuleCachePath)) {
|
||||
SpecificModuleCachePath, /*RequireStrictOptionMatches=*/true)) {
|
||||
PPOpts.ImplicitPCHInclude = std::string(Dir->path());
|
||||
Found = true;
|
||||
break;
|
||||
|
@ -1711,6 +1711,80 @@ bool Sema::CheckRedeclarationInModule(NamedDecl *New, NamedDecl *Old) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the redefinition in C++20 Modules.
|
||||
//
|
||||
// [basic.def.odr]p14:
|
||||
// For any definable item D with definitions in multiple translation units,
|
||||
// - if D is a non-inline non-templated function or variable, or
|
||||
// - if the definitions in different translation units do not satisfy the
|
||||
// following requirements,
|
||||
// the program is ill-formed; a diagnostic is required only if the definable
|
||||
// item is attached to a named module and a prior definition is reachable at
|
||||
// the point where a later definition occurs.
|
||||
// - Each such definition shall not be attached to a named module
|
||||
// ([module.unit]).
|
||||
// - Each such definition shall consist of the same sequence of tokens, ...
|
||||
// ...
|
||||
//
|
||||
// Return true if the redefinition is not allowed. Return false otherwise.
|
||||
bool Sema::IsRedefinitionInModule(const NamedDecl *New,
|
||||
const NamedDecl *Old) const {
|
||||
assert(getASTContext().isSameEntity(New, Old) &&
|
||||
"New and Old are not the same definition, we should diagnostic it "
|
||||
"immediately instead of checking it.");
|
||||
assert(const_cast<Sema *>(this)->isReachable(New) &&
|
||||
const_cast<Sema *>(this)->isReachable(Old) &&
|
||||
"We shouldn't see unreachable definitions here.");
|
||||
|
||||
Module *NewM = New->getOwningModule();
|
||||
Module *OldM = Old->getOwningModule();
|
||||
|
||||
// We only checks for named modules here. The header like modules is skipped.
|
||||
// FIXME: This is not right if we import the header like modules in the module
|
||||
// purview.
|
||||
//
|
||||
// For example, assuming "header.h" provides definition for `D`.
|
||||
// ```C++
|
||||
// //--- M.cppm
|
||||
// export module M;
|
||||
// import "header.h"; // or #include "header.h" but import it by clang modules
|
||||
// actually.
|
||||
//
|
||||
// //--- Use.cpp
|
||||
// import M;
|
||||
// import "header.h"; // or uses clang modules.
|
||||
// ```
|
||||
//
|
||||
// In this case, `D` has multiple definitions in multiple TU (M.cppm and
|
||||
// Use.cpp) and `D` is attached to a named module `M`. The compiler should
|
||||
// reject it. But the current implementation couldn't detect the case since we
|
||||
// don't record the information about the importee modules.
|
||||
//
|
||||
// But this might not be painful in practice. Since the design of C++20 Named
|
||||
// Modules suggests us to use headers in global module fragment instead of
|
||||
// module purview.
|
||||
if (NewM && NewM->isHeaderLikeModule())
|
||||
NewM = nullptr;
|
||||
if (OldM && OldM->isHeaderLikeModule())
|
||||
OldM = nullptr;
|
||||
|
||||
if (!NewM && !OldM)
|
||||
return true;
|
||||
|
||||
// [basic.def.odr]p14.3
|
||||
// Each such definition shall not be attached to a named module
|
||||
// ([module.unit]).
|
||||
if ((NewM && NewM->isModulePurview()) || (OldM && OldM->isModulePurview()))
|
||||
return true;
|
||||
|
||||
// Then New and Old lives in the same TU if their share one same module unit.
|
||||
if (NewM)
|
||||
NewM = NewM->getTopLevelModule();
|
||||
if (OldM)
|
||||
OldM = OldM->getTopLevelModule();
|
||||
return OldM == NewM;
|
||||
}
|
||||
|
||||
static bool isUsingDecl(NamedDecl *D) {
|
||||
return isa<UsingShadowDecl>(D) ||
|
||||
isa<UnresolvedUsingTypenameDecl>(D) ||
|
||||
@ -3960,7 +4034,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, Scope *S,
|
||||
// default argument promotion rules were already checked by
|
||||
// ASTContext::typesAreCompatible().
|
||||
if (Old->hasPrototype() && !New->hasWrittenPrototype() && NewDeclIsDefn &&
|
||||
Old->getNumParams() != New->getNumParams()) {
|
||||
Old->getNumParams() != New->getNumParams() && !Old->isImplicit()) {
|
||||
if (Old->hasInheritedPrototype())
|
||||
Old = Old->getCanonicalDecl();
|
||||
Diag(New->getLocation(), diag::err_conflicting_types) << New;
|
||||
|
@ -63,9 +63,8 @@ static ExprResult CreateFunctionRefExpr(
|
||||
// being used.
|
||||
if (FoundDecl != Fn && S.DiagnoseUseOfDecl(Fn, Loc))
|
||||
return ExprError();
|
||||
DeclRefExpr *DRE =
|
||||
DeclRefExpr::Create(S.Context, Fn->getQualifierLoc(), SourceLocation(),
|
||||
Fn, false, Loc, Fn->getType(), VK_LValue, FoundDecl);
|
||||
DeclRefExpr *DRE = new (S.Context)
|
||||
DeclRefExpr(S.Context, Fn, false, Fn->getType(), VK_LValue, Loc, LocInfo);
|
||||
if (HadMultipleCandidates)
|
||||
DRE->setHadMultipleCandidates(true);
|
||||
|
||||
|
@ -8728,7 +8728,7 @@ void Sema::CheckConceptRedefinition(ConceptDecl *NewDecl,
|
||||
if (Previous.empty())
|
||||
return;
|
||||
|
||||
auto *OldConcept = dyn_cast<ConceptDecl>(Previous.getRepresentativeDecl());
|
||||
auto *OldConcept = dyn_cast<ConceptDecl>(Previous.getRepresentativeDecl()->getUnderlyingDecl());
|
||||
if (!OldConcept) {
|
||||
auto *Old = Previous.getRepresentativeDecl();
|
||||
Diag(NewDecl->getLocation(), diag::err_redefinition_different_kind)
|
||||
@ -8746,7 +8746,8 @@ void Sema::CheckConceptRedefinition(ConceptDecl *NewDecl,
|
||||
AddToScope = false;
|
||||
return;
|
||||
}
|
||||
if (hasReachableDefinition(OldConcept)) {
|
||||
if (hasReachableDefinition(OldConcept) &&
|
||||
IsRedefinitionInModule(NewDecl, OldConcept)) {
|
||||
Diag(NewDecl->getLocation(), diag::err_redefinition)
|
||||
<< NewDecl->getDeclName();
|
||||
notePreviousDefinition(OldConcept, NewDecl->getLocation());
|
||||
@ -8758,7 +8759,8 @@ void Sema::CheckConceptRedefinition(ConceptDecl *NewDecl,
|
||||
// Other decls (e.g. namespaces) also have this shortcoming.
|
||||
return;
|
||||
}
|
||||
Context.setPrimaryMergedDecl(NewDecl, OldConcept);
|
||||
// We unwrap canonical decl late to check for module visibility.
|
||||
Context.setPrimaryMergedDecl(NewDecl, OldConcept->getCanonicalDecl());
|
||||
}
|
||||
|
||||
/// \brief Strips various properties off an implicit instantiation
|
||||
|
@ -624,20 +624,28 @@ collectMacroDefinitions(const PreprocessorOptions &PPOpts,
|
||||
}
|
||||
}
|
||||
|
||||
enum OptionValidation {
|
||||
OptionValidateNone,
|
||||
OptionValidateContradictions,
|
||||
OptionValidateStrictMatches,
|
||||
};
|
||||
|
||||
/// Check the preprocessor options deserialized from the control block
|
||||
/// against the preprocessor options in an existing preprocessor.
|
||||
///
|
||||
/// \param Diags If non-null, produce diagnostics for any mismatches incurred.
|
||||
/// \param Validate If true, validate preprocessor options. If false, allow
|
||||
/// macros defined by \p ExistingPPOpts to override those defined by
|
||||
/// \p PPOpts in SuggestedPredefines.
|
||||
static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts,
|
||||
const PreprocessorOptions &ExistingPPOpts,
|
||||
DiagnosticsEngine *Diags,
|
||||
FileManager &FileMgr,
|
||||
std::string &SuggestedPredefines,
|
||||
const LangOptions &LangOpts,
|
||||
bool Validate = true) {
|
||||
/// \param Validation If set to OptionValidateNone, ignore differences in
|
||||
/// preprocessor options. If set to OptionValidateContradictions,
|
||||
/// require that options passed both in the AST file and on the command
|
||||
/// line (-D or -U) match, but tolerate options missing in one or the
|
||||
/// other. If set to OptionValidateContradictions, require that there
|
||||
/// are no differences in the options between the two.
|
||||
static bool checkPreprocessorOptions(
|
||||
const PreprocessorOptions &PPOpts,
|
||||
const PreprocessorOptions &ExistingPPOpts, DiagnosticsEngine *Diags,
|
||||
FileManager &FileMgr, std::string &SuggestedPredefines,
|
||||
const LangOptions &LangOpts,
|
||||
OptionValidation Validation = OptionValidateContradictions) {
|
||||
// Check macro definitions.
|
||||
MacroDefinitionsMap ASTFileMacros;
|
||||
collectMacroDefinitions(PPOpts, ASTFileMacros);
|
||||
@ -653,7 +661,15 @@ static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts,
|
||||
// Check whether we know anything about this macro name or not.
|
||||
llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/>>::iterator Known =
|
||||
ASTFileMacros.find(MacroName);
|
||||
if (!Validate || Known == ASTFileMacros.end()) {
|
||||
if (Validation == OptionValidateNone || Known == ASTFileMacros.end()) {
|
||||
if (Validation == OptionValidateStrictMatches) {
|
||||
// If strict matches are requested, don't tolerate any extra defines on
|
||||
// the command line that are missing in the AST file.
|
||||
if (Diags) {
|
||||
Diags->Report(diag::err_pch_macro_def_undef) << MacroName << true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// FIXME: Check whether this identifier was referenced anywhere in the
|
||||
// AST file. If so, we should reject the AST file. Unfortunately, this
|
||||
// information isn't in the control block. What shall we do about it?
|
||||
@ -684,8 +700,10 @@ static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts,
|
||||
|
||||
// If the macro was #undef'd in both, or if the macro bodies are identical,
|
||||
// it's fine.
|
||||
if (Existing.second || Existing.first == Known->second.first)
|
||||
if (Existing.second || Existing.first == Known->second.first) {
|
||||
ASTFileMacros.erase(Known);
|
||||
continue;
|
||||
}
|
||||
|
||||
// The macro bodies differ; complain.
|
||||
if (Diags) {
|
||||
@ -694,9 +712,20 @@ static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts,
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (Validation == OptionValidateStrictMatches) {
|
||||
// If strict matches are requested, don't tolerate any extra defines in
|
||||
// the AST file that are missing on the command line.
|
||||
for (const auto &MacroName : ASTFileMacros.keys()) {
|
||||
if (Diags) {
|
||||
Diags->Report(diag::err_pch_macro_def_undef) << MacroName << false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether we're using predefines.
|
||||
if (PPOpts.UsePredefines != ExistingPPOpts.UsePredefines && Validate) {
|
||||
if (PPOpts.UsePredefines != ExistingPPOpts.UsePredefines &&
|
||||
Validation != OptionValidateNone) {
|
||||
if (Diags) {
|
||||
Diags->Report(diag::err_pch_undef) << ExistingPPOpts.UsePredefines;
|
||||
}
|
||||
@ -705,7 +734,8 @@ static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts,
|
||||
|
||||
// Detailed record is important since it is used for the module cache hash.
|
||||
if (LangOpts.Modules &&
|
||||
PPOpts.DetailedRecord != ExistingPPOpts.DetailedRecord && Validate) {
|
||||
PPOpts.DetailedRecord != ExistingPPOpts.DetailedRecord &&
|
||||
Validation != OptionValidateNone) {
|
||||
if (Diags) {
|
||||
Diags->Report(diag::err_pch_pp_detailed_record) << PPOpts.DetailedRecord;
|
||||
}
|
||||
@ -766,13 +796,9 @@ bool SimpleASTReaderListener::ReadPreprocessorOptions(
|
||||
const PreprocessorOptions &PPOpts,
|
||||
bool Complain,
|
||||
std::string &SuggestedPredefines) {
|
||||
return checkPreprocessorOptions(PPOpts,
|
||||
PP.getPreprocessorOpts(),
|
||||
nullptr,
|
||||
PP.getFileManager(),
|
||||
SuggestedPredefines,
|
||||
PP.getLangOpts(),
|
||||
false);
|
||||
return checkPreprocessorOptions(PPOpts, PP.getPreprocessorOpts(), nullptr,
|
||||
PP.getFileManager(), SuggestedPredefines,
|
||||
PP.getLangOpts(), OptionValidateNone);
|
||||
}
|
||||
|
||||
/// Check the header search options deserialized from the control block
|
||||
@ -5138,16 +5164,19 @@ namespace {
|
||||
const PreprocessorOptions &ExistingPPOpts;
|
||||
std::string ExistingModuleCachePath;
|
||||
FileManager &FileMgr;
|
||||
bool StrictOptionMatches;
|
||||
|
||||
public:
|
||||
SimplePCHValidator(const LangOptions &ExistingLangOpts,
|
||||
const TargetOptions &ExistingTargetOpts,
|
||||
const PreprocessorOptions &ExistingPPOpts,
|
||||
StringRef ExistingModuleCachePath, FileManager &FileMgr)
|
||||
StringRef ExistingModuleCachePath, FileManager &FileMgr,
|
||||
bool StrictOptionMatches)
|
||||
: ExistingLangOpts(ExistingLangOpts),
|
||||
ExistingTargetOpts(ExistingTargetOpts),
|
||||
ExistingPPOpts(ExistingPPOpts),
|
||||
ExistingModuleCachePath(ExistingModuleCachePath), FileMgr(FileMgr) {}
|
||||
ExistingModuleCachePath(ExistingModuleCachePath), FileMgr(FileMgr),
|
||||
StrictOptionMatches(StrictOptionMatches) {}
|
||||
|
||||
bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
|
||||
bool AllowCompatibleDifferences) override {
|
||||
@ -5172,9 +5201,11 @@ namespace {
|
||||
bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
|
||||
bool Complain,
|
||||
std::string &SuggestedPredefines) override {
|
||||
return checkPreprocessorOptions(PPOpts, ExistingPPOpts, /*Diags=*/nullptr,
|
||||
FileMgr, SuggestedPredefines,
|
||||
ExistingLangOpts);
|
||||
return checkPreprocessorOptions(
|
||||
PPOpts, ExistingPPOpts, /*Diags=*/nullptr, FileMgr,
|
||||
SuggestedPredefines, ExistingLangOpts,
|
||||
StrictOptionMatches ? OptionValidateStrictMatches
|
||||
: OptionValidateContradictions);
|
||||
}
|
||||
};
|
||||
|
||||
@ -5451,9 +5482,11 @@ bool ASTReader::isAcceptableASTFile(StringRef Filename, FileManager &FileMgr,
|
||||
const LangOptions &LangOpts,
|
||||
const TargetOptions &TargetOpts,
|
||||
const PreprocessorOptions &PPOpts,
|
||||
StringRef ExistingModuleCachePath) {
|
||||
StringRef ExistingModuleCachePath,
|
||||
bool RequireStrictOptionMatches) {
|
||||
SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts,
|
||||
ExistingModuleCachePath, FileMgr);
|
||||
ExistingModuleCachePath, FileMgr,
|
||||
RequireStrictOptionMatches);
|
||||
return !readASTFileControlBlock(Filename, FileMgr, PCHContainerRdr,
|
||||
/*FindModuleFileExtensions=*/false,
|
||||
validator,
|
||||
|
@ -60,7 +60,7 @@ typedef uint16_t dst_rep_t;
|
||||
static const int dstSigBits = 10;
|
||||
|
||||
#elif defined DST_BFLOAT
|
||||
typedef uint16_t dst_t;
|
||||
typedef __bf16 dst_t;
|
||||
typedef uint16_t dst_rep_t;
|
||||
#define DST_REP_C UINT16_C
|
||||
static const int dstSigBits = 7;
|
||||
|
@ -64,7 +64,7 @@ typedef union {
|
||||
} udwords;
|
||||
|
||||
#if defined(__LP64__) || defined(__wasm__) || defined(__mips64) || \
|
||||
defined(__riscv) || defined(_WIN64) || defined(__powerpc__)
|
||||
defined(__riscv) || defined(_WIN64)
|
||||
#define CRT_HAS_128BIT
|
||||
#endif
|
||||
|
||||
|
@ -90,7 +90,7 @@
|
||||
# else
|
||||
# define SANITIZER_IOSSIM 0
|
||||
# endif
|
||||
# if TARGET_OS_DRIVERKIT
|
||||
# if defined(TARGET_OS_DRIVERKIT) && TARGET_OS_DRIVERKIT
|
||||
# define SANITIZER_DRIVERKIT 1
|
||||
# else
|
||||
# define SANITIZER_DRIVERKIT 0
|
||||
|
@ -11,8 +11,10 @@
|
||||
#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
|
||||
@ -20,25 +22,31 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
|
||||
adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) {
|
||||
if (__first != __last) {
|
||||
_ForwardIterator __i = __first;
|
||||
while (++__i != __last) {
|
||||
if (__pred(*__first, *__i))
|
||||
return __first;
|
||||
__first = __i;
|
||||
}
|
||||
template <class _Iter, class _Sent, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _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 __last;
|
||||
return __i;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
|
||||
adjacent_find(_ForwardIterator __first, _ForwardIterator __last) {
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type __v;
|
||||
return _VSTD::adjacent_find(__first, __last, __equal_to<__v>());
|
||||
return std::adjacent_find(std::move(__first), std::move(__last), __equal_to<__v>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
template<class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
|
||||
_LIBCPP_INLINE_VISIBILITY constexpr
|
||||
const _Tp&
|
||||
clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp)
|
||||
{
|
||||
@ -33,7 +33,7 @@ clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp)
|
||||
|
||||
template<class _Tp>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
|
||||
_LIBCPP_INLINE_VISIBILITY constexpr
|
||||
const _Tp&
|
||||
clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi)
|
||||
{
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define _LIBCPP___ALGORITHM_COPY_H
|
||||
|
||||
#include <__algorithm/unwrap_iter.h>
|
||||
#include <__algorithm/unwrap_range.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/reverse_iterator.h>
|
||||
@ -88,10 +89,11 @@ template <class _InIter, class _Sent, class _OutIter,
|
||||
&& is_copy_constructible<_Sent>::value
|
||||
&& is_copy_constructible<_OutIter>::value, int> = 0>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
pair<_InIter, _OutIter>
|
||||
__copy(_InIter __first, _Sent __last, _OutIter __result) {
|
||||
auto __ret = std::__copy_impl(std::__unwrap_iter(__first), std::__unwrap_iter(__last), std::__unwrap_iter(__result));
|
||||
return std::make_pair(std::__rewrap_iter(__first, __ret.first), std::__rewrap_iter(__result, __ret.second));
|
||||
pair<_InIter, _OutIter> __copy(_InIter __first, _Sent __last, _OutIter __result) {
|
||||
auto __range = std::__unwrap_range(__first, __last);
|
||||
auto __ret = std::__copy_impl(std::move(__range.first), std::move(__range.second), std::__unwrap_iter(__result));
|
||||
return std::make_pair(
|
||||
std::__rewrap_range<_Sent>(__first, __ret.first), std::__rewrap_iter(__result, __ret.second));
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _OutputIterator>
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <__ranges/subrange.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
@ -44,9 +43,10 @@ __copy_backward(_InputIterator __first, _InputIterator __last, _OutputIterator _
|
||||
template <class _AlgPolicy, class _Iter1, class _Sent1, class _Iter2,
|
||||
__enable_if_t<is_same<_AlgPolicy, _RangeAlgPolicy>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr pair<_Iter1, _Iter2> __copy_backward(_Iter1 __first, _Sent1 __last, _Iter2 __result) {
|
||||
auto __reverse_range = std::__reverse_range(std::ranges::subrange(std::move(__first), std::move(__last)));
|
||||
auto __last_iter = _IterOps<_AlgPolicy>::next(__first, std::move(__last));
|
||||
auto __reverse_range = std::__reverse_range(std::ranges::subrange(std::move(__first), __last_iter));
|
||||
auto __ret = ranges::copy(std::move(__reverse_range), std::make_reverse_iterator(__result));
|
||||
return std::make_pair(__ret.in.base(), __ret.out.base());
|
||||
return std::make_pair(__last_iter, __ret.out.base());
|
||||
}
|
||||
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
_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_AFTER_CXX17
|
||||
void
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
_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_AFTER_CXX17
|
||||
_OutputIterator
|
||||
|
@ -24,7 +24,8 @@ template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredica
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1 __find_first_of_ce(_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2, _BinaryPredicate __pred) {
|
||||
_ForwardIterator2 __last2,
|
||||
_BinaryPredicate&& __pred) {
|
||||
for (; __first1 != __last1; ++__first1)
|
||||
for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
|
||||
if (__pred(*__first1, *__j))
|
||||
|
@ -54,18 +54,17 @@ class __invert // invert the sense of a comparison
|
||||
bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);}
|
||||
};
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _InputIterator1, class _InputIterator2,
|
||||
class _OutputIterator>
|
||||
void __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1,
|
||||
_InputIterator2 __first2, _InputIterator2 __last2,
|
||||
_OutputIterator __result, _Compare __comp)
|
||||
template <class _AlgPolicy, class _Compare, class _InputIterator1, class _Sent1,
|
||||
class _InputIterator2, class _Sent2, class _OutputIterator>
|
||||
void __half_inplace_merge(_InputIterator1 __first1, _Sent1 __last1,
|
||||
_InputIterator2 __first2, _Sent2 __last2,
|
||||
_OutputIterator __result, _Compare&& __comp)
|
||||
{
|
||||
for (; __first1 != __last1; ++__result)
|
||||
{
|
||||
if (__first2 == __last2)
|
||||
{
|
||||
// TODO(alg-policy): pass `_AlgPolicy` once it's supported by `move`.
|
||||
_VSTD::move(__first1, __last1, __result);
|
||||
std::__move<_AlgPolicy>(__first1, __last1, __result);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -84,13 +83,15 @@ void __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1,
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
|
||||
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;
|
||||
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)
|
||||
@ -98,7 +99,7 @@ __buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator
|
||||
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, _Compare>(__buff, __p, __middle, __last, __first, __comp);
|
||||
std::__half_inplace_merge<_AlgPolicy>(__buff, __p, __middle, __last, __first, __comp);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -108,19 +109,22 @@ __buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator
|
||||
typedef __unconstrained_reverse_iterator<_BidirectionalIterator> _RBi;
|
||||
typedef __unconstrained_reverse_iterator<value_type*> _Rv;
|
||||
typedef __invert<_Compare> _Inverted;
|
||||
std::__half_inplace_merge<_AlgPolicy, _Inverted>(_Rv(__p), _Rv(__buff),
|
||||
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)
|
||||
{
|
||||
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;
|
||||
@ -130,7 +134,7 @@ __inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle,
|
||||
if (__len2 == 0)
|
||||
return;
|
||||
if (__len1 <= __buff_size || __len2 <= __buff_size)
|
||||
return std::__buffered_inplace_merge<_AlgPolicy, _Compare>
|
||||
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)
|
||||
@ -158,8 +162,7 @@ __inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle,
|
||||
__len21 = __len2 / 2;
|
||||
__m2 = __middle;
|
||||
_Ops::advance(__m2, __len21);
|
||||
// TODO: replace _ClassicAlgPolicy and __identity with _AlgPolicy and projection
|
||||
__m1 = std::__upper_bound<_ClassicAlgPolicy>(__first, __middle, *__m2, __comp, std::__identity());
|
||||
__m1 = std::__upper_bound<_AlgPolicy>(__first, __middle, *__m2, __comp, std::__identity());
|
||||
__len11 = _Ops::distance(__first, __m1);
|
||||
}
|
||||
else
|
||||
@ -181,15 +184,13 @@ __inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle,
|
||||
difference_type __len22 = __len2 - __len21; // distance(__m2, __last)
|
||||
// [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last)
|
||||
// swap middle two partitions
|
||||
// TODO(alg-policy): pass `_AlgPolicy` once it's supported by `rotate`.
|
||||
__middle = _VSTD::rotate(__m1, __middle, __m2);
|
||||
__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, _Compare>(
|
||||
std::__inplace_merge<_AlgPolicy>(
|
||||
__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
|
||||
// _VSTD::__inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
|
||||
__first = __middle;
|
||||
__middle = __m2;
|
||||
__len1 = __len12;
|
||||
@ -197,9 +198,8 @@ __inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle,
|
||||
}
|
||||
else
|
||||
{
|
||||
std::__inplace_merge<_AlgPolicy, _Compare>(
|
||||
std::__inplace_merge<_AlgPolicy>(
|
||||
__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
|
||||
// _VSTD::__inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
|
||||
__last = __middle;
|
||||
__middle = __m1;
|
||||
__len1 = __len11;
|
||||
@ -208,33 +208,40 @@ __inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle,
|
||||
}
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator, class _Compare>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
template <class _AlgPolicy, class _BidirectionalIterator, class _Compare>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
void
|
||||
inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
|
||||
_Compare __comp)
|
||||
__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 = _VSTD::distance(__first, __middle);
|
||||
difference_type __len2 = _VSTD::distance(__middle, __last);
|
||||
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);
|
||||
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
|
||||
return _VSTD::__inplace_merge<_ClassicAlgPolicy, _Comp_ref>(__first, __middle, __last, __comp, __len1, __len2,
|
||||
__buf.first, __buf.second);
|
||||
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) {
|
||||
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
|
||||
std::__inplace_merge<_ClassicAlgPolicy>(
|
||||
std::move(__first), std::move(__middle), std::move(__last), static_cast<_Comp_ref>(__comp));
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
void
|
||||
inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last)
|
||||
{
|
||||
_VSTD::inplace_merge(__first, __middle, __last,
|
||||
std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last),
|
||||
__less<typename iterator_traits<_BidirectionalIterator>::value_type>());
|
||||
}
|
||||
|
||||
|
@ -11,10 +11,16 @@
|
||||
#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 <__utility/move.h>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
@ -22,140 +28,211 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
|
||||
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
|
||||
_BinaryPredicate __pred) {
|
||||
// shorten sequences as much as possible by lopping of any equal prefix
|
||||
for (; __first1 != __last1; ++__first1, (void)++__first2)
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class = void>
|
||||
struct _ConstTimeDistance : false_type {};
|
||||
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
|
||||
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 > 17
|
||||
|
||||
// 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_AFTER_CXX17 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_AFTER_CXX17 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
|
||||
typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;
|
||||
_D1 __l1 = _VSTD::distance(__first1, __last1);
|
||||
using _D1 = __iter_diff_t<_ForwardIterator1>;
|
||||
_D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1);
|
||||
if (__l1 == _D1(1))
|
||||
return false;
|
||||
_ForwardIterator2 __last2 = _VSTD::next(__first2, __l1);
|
||||
// For each element in [f1, l1) see if there are the same number of
|
||||
// equal elements in [f2, l2)
|
||||
for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) {
|
||||
// Have we already counted the number of *__i in [f1, l1)?
|
||||
_ForwardIterator1 __match = __first1;
|
||||
for (; __match != __i; ++__match)
|
||||
if (__pred(*__match, *__i))
|
||||
break;
|
||||
if (__match == __i) {
|
||||
// Count number of *__i in [f2, l2)
|
||||
_D1 __c2 = 0;
|
||||
for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
|
||||
if (__pred(*__i, *__j))
|
||||
++__c2;
|
||||
if (__c2 == 0)
|
||||
return false;
|
||||
// Count number of *__i in [__i, l1) (we can start with 1)
|
||||
_D1 __c1 = 1;
|
||||
for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j)
|
||||
if (__pred(*__i, *__j))
|
||||
++__c1;
|
||||
if (__c1 != __c2)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
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());
|
||||
}
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
|
||||
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
|
||||
typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
|
||||
typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
|
||||
return _VSTD::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>());
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER > 11
|
||||
template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
|
||||
__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2, _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag) {
|
||||
// shorten sequences as much as possible by lopping of any equal prefix
|
||||
for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2)
|
||||
if (!__pred(*__first1, *__first2))
|
||||
// 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_AFTER_CXX17 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;
|
||||
else if (__first2 == __last2)
|
||||
if (__first2 == __last2) // Second range is shorter
|
||||
return false;
|
||||
|
||||
typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;
|
||||
_D1 __l1 = _VSTD::distance(__first1, __last1);
|
||||
using _D1 = __iter_diff_t<_Iter1>;
|
||||
_D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1);
|
||||
|
||||
typedef typename iterator_traits<_ForwardIterator2>::difference_type _D2;
|
||||
_D2 __l2 = _VSTD::distance(__first2, __last2);
|
||||
using _D2 = __iter_diff_t<_Iter2>;
|
||||
_D2 __l2 = _IterOps<_AlgPolicy>::distance(__first2, __last2);
|
||||
if (__l1 != __l2)
|
||||
return false;
|
||||
|
||||
// For each element in [f1, l1) see if there are the same number of
|
||||
// equal elements in [f2, l2)
|
||||
for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) {
|
||||
// Have we already counted the number of *__i in [f1, l1)?
|
||||
_ForwardIterator1 __match = __first1;
|
||||
for (; __match != __i; ++__match)
|
||||
if (__pred(*__match, *__i))
|
||||
break;
|
||||
if (__match == __i) {
|
||||
// Count number of *__i in [f2, l2)
|
||||
_D1 __c2 = 0;
|
||||
for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
|
||||
if (__pred(*__i, *__j))
|
||||
++__c2;
|
||||
if (__c2 == 0)
|
||||
return false;
|
||||
// Count number of *__i in [__i, l1) (we can start with 1)
|
||||
_D1 __c1 = 1;
|
||||
for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j)
|
||||
if (__pred(*__i, *__j))
|
||||
++__c1;
|
||||
if (__c1 != __c2)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return std::__is_permutation_impl<_AlgPolicy>(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
|
||||
__pred, __proj1, __proj2);
|
||||
}
|
||||
|
||||
template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 bool __is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1,
|
||||
_RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2,
|
||||
_BinaryPredicate __pred, random_access_iterator_tag,
|
||||
random_access_iterator_tag) {
|
||||
if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
|
||||
// 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_AFTER_CXX17 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 _VSTD::is_permutation<_RandomAccessIterator1, _RandomAccessIterator2,
|
||||
_BinaryPredicate&>(__first1, __last1, __first2, __pred);
|
||||
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_AFTER_CXX17 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 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
|
||||
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2, _BinaryPredicate __pred) {
|
||||
return _VSTD::__is_permutation<_BinaryPredicate&>(
|
||||
__first1, __last1, __first2, __last2, __pred, typename iterator_traits<_ForwardIterator1>::iterator_category(),
|
||||
typename iterator_traits<_ForwardIterator2>::iterator_category());
|
||||
_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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
|
||||
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
|
||||
using __v1 = __iter_value_type<_ForwardIterator1>;
|
||||
using __v2 = __iter_value_type<_ForwardIterator2>;
|
||||
return std::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>());
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER > 11
|
||||
|
||||
// 2+2 iterators
|
||||
template <class _ForwardIterator1, class _ForwardIterator2>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
|
||||
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2) {
|
||||
typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
|
||||
typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
|
||||
return _VSTD::__is_permutation(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(),
|
||||
typename iterator_traits<_ForwardIterator1>::iterator_category(),
|
||||
typename iterator_traits<_ForwardIterator2>::iterator_category());
|
||||
using __v1 = __iter_value_type<_ForwardIterator1>;
|
||||
using __v2 = __iter_value_type<_ForwardIterator2>;
|
||||
|
||||
return std::__is_permutation<_ClassicAlgPolicy>(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
|
||||
__equal_to<__v1, __v2>(), __identity(), __identity());
|
||||
}
|
||||
#endif
|
||||
|
||||
// 2+2 iterators, predicate
|
||||
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 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 > 11
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -10,13 +10,18 @@
|
||||
#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 <__utility/declval.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/move.h>
|
||||
#include <type_traits>
|
||||
@ -34,11 +39,22 @@ 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;
|
||||
};
|
||||
|
||||
@ -49,6 +65,15 @@ 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_AFTER_CXX11
|
||||
@ -63,24 +88,46 @@ struct _IterOps<_ClassicAlgPolicy> {
|
||||
return std::distance(__first, __last);
|
||||
}
|
||||
|
||||
// iter_move
|
||||
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_AFTER_CXX11
|
||||
// Declaring the return type is necessary for C++03, so we basically mirror what `decltype(auto)` would deduce.
|
||||
static __enable_if_t<
|
||||
is_reference<typename iterator_traits<__uncvref_t<_Iter> >::reference>::value,
|
||||
typename remove_reference< typename iterator_traits<__uncvref_t<_Iter> >::reference >::type&&>
|
||||
__iter_move(_Iter&& __i) {
|
||||
static void __validate_iter_reference() {
|
||||
static_assert(is_same<__deref_t<_Iter>, typename iterator_traits<__uncvref_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_AFTER_CXX11 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_AFTER_CXX11
|
||||
// Declaring the return type is necessary for C++03, so we basically mirror what `decltype(auto)` would deduce.
|
||||
static __enable_if_t<
|
||||
!is_reference<typename iterator_traits<__uncvref_t<_Iter> >::reference>::value,
|
||||
typename iterator_traits<__uncvref_t<_Iter> >::reference>
|
||||
__iter_move(_Iter&& __i) {
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 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);
|
||||
}
|
||||
|
||||
@ -100,11 +147,19 @@ struct _IterOps<_ClassicAlgPolicy> {
|
||||
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
__uncvref_t<_Iter> next(_Iter&& __it,
|
||||
typename iterator_traits<__uncvref_t<_Iter> >::difference_type __n = 1){
|
||||
__uncvref_t<_Iter> next(_Iter&& __it,
|
||||
typename iterator_traits<__uncvref_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_AFTER_CXX11
|
||||
__uncvref_t<_Iter> prev(_Iter&& __iter,
|
||||
typename iterator_traits<__uncvref_t<_Iter> >::difference_type __n = 1) {
|
||||
return std::prev(std::forward<_Iter>(__iter), __n);
|
||||
}
|
||||
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
void __advance_to(_Iter& __first, _Iter __last) {
|
||||
|
@ -25,7 +25,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) {
|
||||
void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) {
|
||||
using _CompRef = typename __comp_ref_type<_Compare>::type;
|
||||
_CompRef __comp_ref = __comp;
|
||||
|
||||
@ -34,7 +34,7 @@ void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _C
|
||||
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, _CompRef>(__first, __comp_ref, __n, __first + __start);
|
||||
std::__sift_down<_AlgPolicy>(__first, __comp_ref, __n, __first + __start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,51 +14,91 @@
|
||||
#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 _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 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 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, class = void>
|
||||
struct __can_use_pristine_comp : false_type {};
|
||||
|
||||
template <class _Pred, class _Proj>
|
||||
struct __can_use_pristine_comp<_Pred, _Proj, __enable_if_t<
|
||||
!is_member_pointer<typename decay<_Pred>::type>::value && (
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
is_same<typename decay<_Proj>::type, identity>::value ||
|
||||
#endif
|
||||
is_same<typename decay<_Proj>::type, __identity>::value
|
||||
)
|
||||
> > : true_type {};
|
||||
|
||||
template <class _Pred, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static
|
||||
__enable_if_t<
|
||||
!__can_use_pristine_comp<_Pred, _Proj>::value,
|
||||
_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>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static
|
||||
__enable_if_t<
|
||||
__can_use_pristine_comp<_Pred, _Proj>::value,
|
||||
_Pred&
|
||||
>
|
||||
__make_projected(_Pred& __pred, _Proj&) {
|
||||
return __pred;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _Pred, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr static
|
||||
decltype(auto) __make_projected_pred(_Pred& __pred, _Proj& __proj) {
|
||||
if constexpr (same_as<decay_t<_Proj>, identity> && !is_member_pointer_v<decay_t<_Pred>>) {
|
||||
// Avoid creating the lambda and just use the pristine predicate -- for certain algorithms, this would enable
|
||||
// optimizations that rely on the type of the predicate.
|
||||
return __pred;
|
||||
|
||||
} else {
|
||||
return [&](auto&& __x) {
|
||||
return std::invoke(__pred, std::invoke(__proj, std::forward<decltype(__x)>(__x)));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Comp, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr static
|
||||
decltype(auto) __make_projected_comp(_Comp& __comp, _Proj& __proj) {
|
||||
if constexpr (same_as<decay_t<_Proj>, identity> && !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(__proj, std::forward<decltype(__lhs)>(__lhs)),
|
||||
std::invoke(__proj, std::forward<decltype(__rhs)>(__rhs)));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Comp, class _Proj1, class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr static
|
||||
decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) {
|
||||
|
@ -9,6 +9,7 @@
|
||||
#ifndef _LIBCPP___ALGORITHM_MOVE_H
|
||||
#define _LIBCPP___ALGORITHM_MOVE_H
|
||||
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/unwrap_iter.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
@ -26,18 +27,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// move
|
||||
|
||||
template <class _InIter, class _Sent, class _OutIter>
|
||||
template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
pair<_InIter, _OutIter> __move_impl(_InIter __first, _Sent __last, _OutIter __result) {
|
||||
while (__first != __last) {
|
||||
*__result = std::move(*__first);
|
||||
*__result = _IterOps<_AlgPolicy>::__iter_move(__first);
|
||||
++__first;
|
||||
++__result;
|
||||
}
|
||||
return std::make_pair(std::move(__first), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InType,
|
||||
template <class _AlgPolicy,
|
||||
class _InType,
|
||||
class _OutType,
|
||||
class = __enable_if_t<is_same<typename remove_const<_InType>::type, _OutType>::value
|
||||
&& is_trivially_move_assignable<_OutType>::value> >
|
||||
@ -49,7 +51,7 @@ pair<_InType*, _OutType*> __move_impl(_InType* __first, _InType* __last, _OutTyp
|
||||
&& !is_trivially_copyable<_InType>::value
|
||||
#endif
|
||||
)
|
||||
return std::__move_impl<_InType*, _InType*, _OutType*>(__first, __last, __result);
|
||||
return std::__move_impl<_AlgPolicy, _InType*, _InType*, _OutType*>(__first, __last, __result);
|
||||
const size_t __n = static_cast<size_t>(__last - __first);
|
||||
::__builtin_memmove(__result, __first, __n * sizeof(_OutType));
|
||||
return std::make_pair(__first + __n, __result + __n);
|
||||
@ -65,7 +67,8 @@ template <class _Iter>
|
||||
struct __is_trivially_move_assignable_unwrapped
|
||||
: __is_trivially_move_assignable_unwrapped_impl<decltype(std::__unwrap_iter<_Iter>(std::declval<_Iter>()))> {};
|
||||
|
||||
template <class _InIter,
|
||||
template <class _AlgPolicy,
|
||||
class _InIter,
|
||||
class _OutIter,
|
||||
__enable_if_t<is_same<typename remove_const<typename iterator_traits<_InIter>::value_type>::type,
|
||||
typename iterator_traits<_OutIter>::value_type>::value
|
||||
@ -81,33 +84,34 @@ __move_impl(reverse_iterator<_InIter> __first,
|
||||
auto __last_base = std::__unwrap_iter(__last.base());
|
||||
auto __result_base = std::__unwrap_iter(__result.base());
|
||||
auto __result_first = __result_base - (__first_base - __last_base);
|
||||
std::__move_impl(__last_base, __first_base, __result_first);
|
||||
std::__move_impl<_AlgPolicy>(__last_base, __first_base, __result_first);
|
||||
return std::make_pair(__last, reverse_iterator<_OutIter>(std::__rewrap_iter(__result.base(), __result_first)));
|
||||
}
|
||||
|
||||
template <class _InIter, class _Sent, class _OutIter>
|
||||
template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
__enable_if_t<is_copy_constructible<_InIter>::value
|
||||
&& is_copy_constructible<_Sent>::value
|
||||
&& is_copy_constructible<_OutIter>::value, pair<_InIter, _OutIter> >
|
||||
__move(_InIter __first, _Sent __last, _OutIter __result) {
|
||||
auto __ret = std::__move_impl(std::__unwrap_iter(__first), std::__unwrap_iter(__last), std::__unwrap_iter(__result));
|
||||
auto __ret = std::__move_impl<_AlgPolicy>(
|
||||
std::__unwrap_iter(__first), std::__unwrap_iter(__last), std::__unwrap_iter(__result));
|
||||
return std::make_pair(std::__rewrap_iter(__first, __ret.first), std::__rewrap_iter(__result, __ret.second));
|
||||
}
|
||||
|
||||
template <class _InIter, class _Sent, class _OutIter>
|
||||
template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
__enable_if_t<!is_copy_constructible<_InIter>::value
|
||||
|| !is_copy_constructible<_Sent>::value
|
||||
|| !is_copy_constructible<_OutIter>::value, pair<_InIter, _OutIter> >
|
||||
__move(_InIter __first, _Sent __last, _OutIter __result) {
|
||||
return std::__move_impl(std::move(__first), std::move(__last), std::move(__result));
|
||||
return std::__move_impl<_AlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _OutputIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
_OutputIterator move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
|
||||
return std::__move(__first, __last, __result).second;
|
||||
return std::__move<_ClassicAlgPolicy>(__first, __last, __result).second;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
@ -9,6 +9,7 @@
|
||||
#ifndef _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
|
||||
#define _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
|
||||
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/unwrap_iter.h>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
@ -21,25 +22,25 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _OutputIterator>
|
||||
template <class _AlgPolicy, class _InputIterator, class _OutputIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
_OutputIterator
|
||||
__move_backward_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
|
||||
{
|
||||
while (__first != __last)
|
||||
*--__result = _VSTD::move(*--__last);
|
||||
*--__result = _IterOps<_AlgPolicy>::__iter_move(--__last);
|
||||
return __result;
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _OutputIterator>
|
||||
template <class _AlgPolicy, class _InputIterator, class _OutputIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
_OutputIterator
|
||||
__move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
|
||||
__move_backward_impl(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
|
||||
{
|
||||
return _VSTD::__move_backward_constexpr(__first, __last, __result);
|
||||
return _VSTD::__move_backward_constexpr<_AlgPolicy>(__first, __last, __result);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
template <class _AlgPolicy, class _Tp, class _Up>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
typename enable_if
|
||||
<
|
||||
@ -47,7 +48,7 @@ typename enable_if
|
||||
is_trivially_move_assignable<_Up>::value,
|
||||
_Up*
|
||||
>::type
|
||||
__move_backward(_Tp* __first, _Tp* __last, _Up* __result)
|
||||
__move_backward_impl(_Tp* __first, _Tp* __last, _Up* __result)
|
||||
{
|
||||
const size_t __n = static_cast<size_t>(__last - __first);
|
||||
if (__n > 0)
|
||||
@ -58,20 +59,29 @@ __move_backward(_Tp* __first, _Tp* __last, _Up* __result)
|
||||
return __result;
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _BidirectionalIterator1, class _BidirectionalIterator2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
_BidirectionalIterator2
|
||||
__move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
|
||||
_BidirectionalIterator2 __result)
|
||||
{
|
||||
if (__libcpp_is_constant_evaluated()) {
|
||||
return _VSTD::__move_backward_constexpr<_AlgPolicy>(__first, __last, __result);
|
||||
} else {
|
||||
return _VSTD::__rewrap_iter(__result,
|
||||
_VSTD::__move_backward_impl<_AlgPolicy>(_VSTD::__unwrap_iter(__first),
|
||||
_VSTD::__unwrap_iter(__last),
|
||||
_VSTD::__unwrap_iter(__result)));
|
||||
}
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator1, class _BidirectionalIterator2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
_BidirectionalIterator2
|
||||
move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
|
||||
_BidirectionalIterator2 __result)
|
||||
{
|
||||
if (__libcpp_is_constant_evaluated()) {
|
||||
return _VSTD::__move_backward_constexpr(__first, __last, __result);
|
||||
} else {
|
||||
return _VSTD::__rewrap_iter(__result,
|
||||
_VSTD::__move_backward(_VSTD::__unwrap_iter(__first),
|
||||
_VSTD::__unwrap_iter(__last),
|
||||
_VSTD::__unwrap_iter(__result)));
|
||||
}
|
||||
return std::__move_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
@ -11,10 +11,12 @@
|
||||
|
||||
#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/swap.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
@ -22,29 +24,34 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Compare, class _BidirectionalIterator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
|
||||
__next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
|
||||
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator, class _Sentinel>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
pair<_BidirectionalIterator, bool>
|
||||
__next_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp)
|
||||
{
|
||||
_BidirectionalIterator __i = __last;
|
||||
using _Result = pair<_BidirectionalIterator, bool>;
|
||||
|
||||
_BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
|
||||
_BidirectionalIterator __i = __last_iter;
|
||||
if (__first == __last || __first == --__i)
|
||||
return false;
|
||||
return _Result(std::move(__last_iter), false);
|
||||
|
||||
while (true)
|
||||
{
|
||||
_BidirectionalIterator __ip1 = __i;
|
||||
if (__comp(*--__i, *__ip1))
|
||||
{
|
||||
_BidirectionalIterator __j = __last;
|
||||
_BidirectionalIterator __j = __last_iter;
|
||||
while (!__comp(*__i, *--__j))
|
||||
;
|
||||
swap(*__i, *__j);
|
||||
_VSTD::reverse(__ip1, __last);
|
||||
return true;
|
||||
_IterOps<_AlgPolicy>::iter_swap(__i, __j);
|
||||
std::__reverse<_AlgPolicy>(__ip1, __last_iter);
|
||||
return _Result(std::move(__last_iter), true);
|
||||
}
|
||||
if (__i == __first)
|
||||
{
|
||||
_VSTD::reverse(__first, __last);
|
||||
return false;
|
||||
std::__reverse<_AlgPolicy>(__first, __last_iter);
|
||||
return _Result(std::move(__last_iter), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -54,8 +61,9 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
bool
|
||||
next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
|
||||
{
|
||||
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
|
||||
return _VSTD::__next_permutation<_Comp_ref>(__first, __last, __comp);
|
||||
using _Comp_ref = typename __comp_ref_type<_Compare>::type;
|
||||
return std::__next_permutation<_ClassicAlgPolicy>(
|
||||
std::move(__first), std::move(__last), static_cast<_Comp_ref>(__comp)).second;
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator>
|
||||
|
@ -31,12 +31,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
_RandomAccessIterator __partial_sort_impl(
|
||||
_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare __comp) {
|
||||
_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare&& __comp) {
|
||||
if (__first == __middle) {
|
||||
return _IterOps<_AlgPolicy>::next(__middle, __last);
|
||||
}
|
||||
|
||||
std::__make_heap<_AlgPolicy, _Compare>(__first, __middle, __comp);
|
||||
std::__make_heap<_AlgPolicy>(__first, __middle, __comp);
|
||||
|
||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first;
|
||||
_RandomAccessIterator __i = __middle;
|
||||
@ -45,11 +45,11 @@ _RandomAccessIterator __partial_sort_impl(
|
||||
if (__comp(*__i, *__first))
|
||||
{
|
||||
_IterOps<_AlgPolicy>::iter_swap(__i, __first);
|
||||
std::__sift_down<_AlgPolicy, _Compare>(__first, __comp, __len, __first);
|
||||
std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first);
|
||||
}
|
||||
|
||||
}
|
||||
std::__sort_heap<_AlgPolicy, _Compare>(std::move(__first), std::move(__middle), __comp);
|
||||
std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp);
|
||||
|
||||
return __i;
|
||||
}
|
||||
@ -64,7 +64,7 @@ _RandomAccessIterator __partial_sort(_RandomAccessIterator __first, _RandomAcces
|
||||
std::__debug_randomize_range<_AlgPolicy>(__first, __last);
|
||||
|
||||
using _Comp_ref = typename __comp_ref_type<_Compare>::type;
|
||||
auto __last_iter = std::__partial_sort_impl<_AlgPolicy, _Comp_ref>(__first, __middle, __last, __comp);
|
||||
auto __last_iter = std::__partial_sort_impl<_AlgPolicy>(__first, __middle, __last, static_cast<_Comp_ref>(__comp));
|
||||
|
||||
std::__debug_randomize_range<_AlgPolicy>(__middle, __last);
|
||||
|
||||
|
@ -13,10 +13,16 @@
|
||||
#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
|
||||
@ -24,27 +30,33 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _InputIterator, class _RandomAccessIterator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
|
||||
__partial_sort_copy(_InputIterator __first, _InputIterator __last,
|
||||
_RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
|
||||
template <class _AlgPolicy, class _Compare,
|
||||
class _InputIterator, class _Sentinel1, class _RandomAccessIterator, class _Sentinel2,
|
||||
class _Proj1, class _Proj2>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 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, _Compare>(__result_first, __r, __comp);
|
||||
std::__make_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
|
||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first;
|
||||
for (; __first != __last; ++__first)
|
||||
if (__comp(*__first, *__result_first))
|
||||
{
|
||||
if (std::__invoke(__comp, std::__invoke(__proj1, *__first), std::__invoke(__proj2, *__result_first))) {
|
||||
*__result_first = *__first;
|
||||
std::__sift_down<_AlgPolicy, _Compare>(__result_first, __comp, __len, __result_first);
|
||||
std::__sift_down<_AlgPolicy>(__result_first, __projected_comp, __len, __result_first);
|
||||
}
|
||||
std::__sort_heap<_AlgPolicy, _Compare>(__result_first, __r, __comp);
|
||||
std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
|
||||
}
|
||||
return __r;
|
||||
|
||||
return pair<_InputIterator, _RandomAccessIterator>(
|
||||
_IterOps<_AlgPolicy>::next(std::move(__first), std::move(__last)), std::move(__r));
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _RandomAccessIterator, class _Compare>
|
||||
@ -53,9 +65,13 @@ _RandomAccessIterator
|
||||
partial_sort_copy(_InputIterator __first, _InputIterator __last,
|
||||
_RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
|
||||
{
|
||||
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
|
||||
return std::__partial_sort_copy<_ClassicAlgPolicy, _Comp_ref>(
|
||||
__first, __last, __result_first, __result_last, __comp);
|
||||
static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__result_first)>::value,
|
||||
"Comparator has to be callable");
|
||||
|
||||
using _Comp_ref = typename __comp_ref_type<_Compare>::type;
|
||||
auto __result = std::__partial_sort_copy<_ClassicAlgPolicy>(__first, __last, __result_first, __result_last,
|
||||
static_cast<_Comp_ref>(__comp), __identity(), __identity());
|
||||
return __result.second;
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _RandomAccessIterator>
|
||||
|
@ -38,7 +38,7 @@ void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Co
|
||||
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, _CompRef>(__first, __comp_ref, __len);
|
||||
_RandomAccessIterator __hole = std::__floyd_sift_down<_AlgPolicy>(__first, __comp_ref, __len);
|
||||
--__last;
|
||||
|
||||
if (__hole == __last) {
|
||||
@ -47,7 +47,7 @@ void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Co
|
||||
*__hole = _IterOps<_AlgPolicy>::__iter_move(__last);
|
||||
++__hole;
|
||||
*__last = std::move(__top);
|
||||
std::__sift_up<_AlgPolicy, _CompRef>(__first, __hole, __comp_ref, __hole - __first);
|
||||
std::__sift_up<_AlgPolicy>(__first, __hole, __comp_ref, __hole - __first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,10 +11,12 @@
|
||||
|
||||
#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/swap.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
@ -22,29 +24,34 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Compare, class _BidirectionalIterator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
|
||||
__prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
|
||||
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator, class _Sentinel>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
pair<_BidirectionalIterator, bool>
|
||||
__prev_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp)
|
||||
{
|
||||
_BidirectionalIterator __i = __last;
|
||||
using _Result = pair<_BidirectionalIterator, bool>;
|
||||
|
||||
_BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
|
||||
_BidirectionalIterator __i = __last_iter;
|
||||
if (__first == __last || __first == --__i)
|
||||
return false;
|
||||
return _Result(std::move(__last_iter), false);
|
||||
|
||||
while (true)
|
||||
{
|
||||
_BidirectionalIterator __ip1 = __i;
|
||||
if (__comp(*__ip1, *--__i))
|
||||
{
|
||||
_BidirectionalIterator __j = __last;
|
||||
_BidirectionalIterator __j = __last_iter;
|
||||
while (!__comp(*--__j, *__i))
|
||||
;
|
||||
swap(*__i, *__j);
|
||||
_VSTD::reverse(__ip1, __last);
|
||||
return true;
|
||||
_IterOps<_AlgPolicy>::iter_swap(__i, __j);
|
||||
std::__reverse<_AlgPolicy>(__ip1, __last_iter);
|
||||
return _Result(std::move(__last_iter), true);
|
||||
}
|
||||
if (__i == __first)
|
||||
{
|
||||
_VSTD::reverse(__first, __last);
|
||||
return false;
|
||||
std::__reverse<_AlgPolicy>(__first, __last_iter);
|
||||
return _Result(std::move(__last_iter), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -54,8 +61,9 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
bool
|
||||
prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
|
||||
{
|
||||
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
|
||||
return _VSTD::__prev_permutation<_Comp_ref>(__first, __last, __comp);
|
||||
using _Comp_ref = typename __comp_ref_type<_Compare>::type;
|
||||
return std::__prev_permutation<_ClassicAlgPolicy>(
|
||||
std::move(__first), std::move(__last), static_cast<_Comp_ref>(__comp)).second;
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator>
|
||||
|
@ -25,7 +25,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
|
||||
void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp,
|
||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
|
||||
using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
|
||||
|
||||
|
@ -0,0 +1,65 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_RANGES_CLAMP_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_CLAMP_H
|
||||
|
||||
#include <__assert>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__utility/forward.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __clamp {
|
||||
struct __fn {
|
||||
|
||||
template <class _Type,
|
||||
class _Proj = identity,
|
||||
indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
const _Type& operator()(const _Type& __value,
|
||||
const _Type& __low,
|
||||
const _Type& __high,
|
||||
_Comp __comp = {},
|
||||
_Proj __proj = {}) const {
|
||||
_LIBCPP_ASSERT(!bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))),
|
||||
"Bad bounds passed to std::ranges::clamp");
|
||||
|
||||
if (std::invoke(__comp, std::invoke(__proj, __value), std::invoke(__proj, __low)))
|
||||
return __low;
|
||||
else if (std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __value)))
|
||||
return __high;
|
||||
else
|
||||
return __value;
|
||||
}
|
||||
|
||||
};
|
||||
} // namespace __clamp
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto clamp = __clamp::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_CLAMP_H
|
@ -10,6 +10,7 @@
|
||||
#define _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H
|
||||
|
||||
#include <__algorithm/inplace_merge.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/make_projected.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
@ -17,6 +18,7 @@
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/next.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__iterator/sortable.h>
|
||||
#include <__ranges/access.h>
|
||||
@ -36,28 +38,38 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
namespace ranges {
|
||||
namespace __inplace_merge {
|
||||
|
||||
struct __fn {
|
||||
struct __fn {
|
||||
template <class _Iter, class _Sent, class _Comp, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr auto
|
||||
__inplace_merge_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
|
||||
auto __last_iter = ranges::next(__middle, __last);
|
||||
std::__inplace_merge<_RangeAlgPolicy>(
|
||||
std::move(__first), std::move(__middle), __last_iter, std::__make_projected(__comp, __proj));
|
||||
return __last_iter;
|
||||
}
|
||||
|
||||
template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
|
||||
requires sortable<_Iter, _Comp, _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Iter operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
// TODO: implement
|
||||
(void)__first; (void)__middle; (void)__last; (void)__comp; (void)__proj;
|
||||
return {};
|
||||
}
|
||||
template <
|
||||
bidirectional_iterator _Iter,
|
||||
sentinel_for<_Iter> _Sent,
|
||||
class _Comp = ranges::less,
|
||||
class _Proj = identity>
|
||||
requires sortable<_Iter, _Comp, _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI _Iter
|
||||
operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
return __inplace_merge_impl(
|
||||
std::move(__first), std::move(__middle), std::move(__last), std::move(__comp), std::move(__proj));
|
||||
}
|
||||
|
||||
template <bidirectional_range _Range, class _Comp = ranges::less, class _Proj = identity>
|
||||
requires sortable<iterator_t<_Range>, _Comp, _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
borrowed_iterator_t<_Range> operator()(_Range&& __range, iterator_t<_Range> __middle,
|
||||
_Comp __comp = {}, _Proj __proj = {}) const {
|
||||
// TODO: implement
|
||||
(void)__range; (void)__middle; (void)__comp; (void)__proj;
|
||||
return {};
|
||||
}
|
||||
|
||||
};
|
||||
template <bidirectional_range _Range, class _Comp = ranges::less, class _Proj = identity>
|
||||
requires sortable<
|
||||
iterator_t<_Range>,
|
||||
_Comp,
|
||||
_Proj> _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range>
|
||||
operator()(_Range&& __range, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
return __inplace_merge_impl(
|
||||
ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__comp), std::move(__proj));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __inplace_merge
|
||||
|
||||
|
@ -39,7 +39,7 @@ struct __fn {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
static bool __is_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
|
||||
auto __last_iter = ranges::next(__first, __last);
|
||||
auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
|
||||
auto&& __projected_comp = std::__make_projected(__comp, __proj);
|
||||
|
||||
auto __result = std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp);
|
||||
return __result == __last;
|
||||
|
@ -40,7 +40,7 @@ struct __fn {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
static _Iter __is_heap_until_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
|
||||
auto __last_iter = ranges::next(__first, __last);
|
||||
auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
|
||||
auto&& __projected_comp = std::__make_projected(__comp, __proj);
|
||||
|
||||
return std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp);
|
||||
}
|
||||
|
@ -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_RANGES_IS_PERMUTATION_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H
|
||||
|
||||
#include <__algorithm/is_permutation.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __is_permutation {
|
||||
struct __fn {
|
||||
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2,
|
||||
class _Proj1, class _Proj2, class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr static
|
||||
bool __is_permutation_func_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
|
||||
_Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
|
||||
return std::__is_permutation<_RangeAlgPolicy>(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
|
||||
__pred, __proj1, __proj2);
|
||||
}
|
||||
|
||||
template <forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
|
||||
forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
|
||||
class _Proj1 = identity,
|
||||
class _Proj2 = identity,
|
||||
indirect_equivalence_relation<projected<_Iter1, _Proj1>,
|
||||
projected<_Iter2, _Proj2>> _Pred = ranges::equal_to>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
bool operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
|
||||
_Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
|
||||
return __is_permutation_func_impl(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
|
||||
__pred, __proj1, __proj2);
|
||||
}
|
||||
|
||||
template <forward_range _Range1,
|
||||
forward_range _Range2,
|
||||
class _Proj1 = identity,
|
||||
class _Proj2 = identity,
|
||||
indirect_equivalence_relation<projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>> _Pred = ranges::equal_to>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
bool operator()(_Range1&& __range1, _Range2&& __range2,
|
||||
_Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
|
||||
if constexpr (sized_range<_Range1> && sized_range<_Range2>) {
|
||||
if (ranges::distance(__range1) != ranges::distance(__range2))
|
||||
return false;
|
||||
}
|
||||
|
||||
return __is_permutation_func_impl(
|
||||
ranges::begin(__range1), ranges::end(__range1), ranges::begin(__range2), ranges::end(__range2),
|
||||
__pred, __proj1, __proj2);
|
||||
}
|
||||
};
|
||||
} // namespace __is_permutation
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto is_permutation = __is_permutation::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H
|
@ -45,7 +45,7 @@ struct __fn {
|
||||
_Iter __make_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
|
||||
auto __last_iter = ranges::next(__first, __last);
|
||||
|
||||
auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
|
||||
auto&& __projected_comp = std::__make_projected(__comp, __proj);
|
||||
std::__make_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp);
|
||||
|
||||
return __last_iter;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define _LIBCPP___ALGORITHM_RANGES_MOVE_H
|
||||
|
||||
#include <__algorithm/in_out_result.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/move.h>
|
||||
#include <__config>
|
||||
#include <__iterator/concepts.h>
|
||||
@ -36,24 +37,12 @@ namespace __move {
|
||||
struct __fn {
|
||||
|
||||
template <class _InIter, class _Sent, class _OutIter>
|
||||
requires __iter_move::__move_deref<_InIter> // check that we are allowed to std::move() the value
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr static
|
||||
move_result<_InIter, _OutIter> __move_impl(_InIter __first, _Sent __last, _OutIter __result) {
|
||||
auto __ret = std::__move(std::move(__first), std::move(__last), std::move(__result));
|
||||
auto __ret = std::__move<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
|
||||
return {std::move(__ret.first), std::move(__ret.second)};
|
||||
}
|
||||
|
||||
template <class _InIter, class _Sent, class _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr static
|
||||
move_result<_InIter, _OutIter> __move_impl(_InIter __first, _Sent __last, _OutIter __result) {
|
||||
while (__first != __last) {
|
||||
*__result = ranges::iter_move(__first);
|
||||
++__first;
|
||||
++__result;
|
||||
}
|
||||
return {std::move(__first), std::move(__result)};
|
||||
}
|
||||
|
||||
template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter>
|
||||
requires indirectly_movable<_InIter, _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
|
@ -40,10 +40,11 @@ struct __fn {
|
||||
template <class _InIter, class _Sent, class _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr static
|
||||
move_backward_result<_InIter, _OutIter> __move_backward_impl(_InIter __first, _Sent __last, _OutIter __result) {
|
||||
auto __ret = ranges::move(std::make_reverse_iterator(ranges::next(__first, __last)),
|
||||
auto __last_iter = ranges::next(__first, std::move(__last));
|
||||
auto __ret = ranges::move(std::make_reverse_iterator(__last_iter),
|
||||
std::make_reverse_iterator(__first),
|
||||
std::make_reverse_iterator(__result));
|
||||
return {std::move(__ret.in.base()), std::move(__ret.out.base())};
|
||||
return {std::move(__last_iter), std::move(__ret.out.base())};
|
||||
}
|
||||
|
||||
template <bidirectional_iterator _InIter, sentinel_for<_InIter> _Sent, bidirectional_iterator _OutIter>
|
||||
|
@ -0,0 +1,72 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_RANGES_NEXT_PERMUTATION_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H
|
||||
|
||||
#include <__algorithm/in_found_result.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/make_projected.h>
|
||||
#include <__algorithm/next_permutation.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/sortable.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/dangling.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _InIter>
|
||||
using next_permutation_result = in_found_result<_InIter>;
|
||||
|
||||
namespace __next_permutation {
|
||||
|
||||
struct __fn {
|
||||
template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
|
||||
requires sortable<_Iter, _Comp, _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr next_permutation_result<_Iter>
|
||||
operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
auto __result = std::__next_permutation<_RangeAlgPolicy>(
|
||||
std::move(__first), std::move(__last), std::__make_projected(__comp, __proj));
|
||||
return {std::move(__result.first), std::move(__result.second)};
|
||||
}
|
||||
|
||||
template <bidirectional_range _Range, class _Comp = ranges::less, class _Proj = identity>
|
||||
requires sortable<iterator_t<_Range>, _Comp, _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr next_permutation_result<borrowed_iterator_t<_Range>>
|
||||
operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
auto __result = std::__next_permutation<_RangeAlgPolicy>(
|
||||
ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj));
|
||||
return {std::move(__result.first), std::move(__result.second)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __next_permutation
|
||||
|
||||
inline namespace __cpo {
|
||||
constexpr inline auto next_permutation = __next_permutation::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H
|
@ -44,7 +44,7 @@ struct __fn {
|
||||
_Iter __nth_element_fn_impl(_Iter __first, _Iter __nth, _Sent __last, _Comp& __comp, _Proj& __proj) {
|
||||
auto __last_iter = ranges::next(__first, __last);
|
||||
|
||||
auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
|
||||
auto&& __projected_comp = std::__make_projected(__comp, __proj);
|
||||
std::__nth_element_impl<_RangeAlgPolicy>(std::move(__first), std::move(__nth), __last_iter, __projected_comp);
|
||||
|
||||
return __last_iter;
|
||||
|
@ -43,7 +43,7 @@ struct __fn {
|
||||
template <class _Iter, class _Sent, class _Comp, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr static
|
||||
_Iter __partial_sort_fn_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp& __comp, _Proj& __proj) {
|
||||
auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
|
||||
auto&& __projected_comp = std::__make_projected(__comp, __proj);
|
||||
return std::__partial_sort<_RangeAlgPolicy>(std::move(__first), std::move(__middle), __last, __projected_comp);
|
||||
}
|
||||
|
||||
|
@ -10,11 +10,11 @@
|
||||
#define _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H
|
||||
|
||||
#include <__algorithm/in_out_result.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/make_projected.h>
|
||||
#include <__algorithm/partial_sort_copy.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
@ -23,7 +23,6 @@
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/dangling.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
@ -52,9 +51,11 @@ struct __fn {
|
||||
partial_sort_copy_result<_Iter1, _Iter2>
|
||||
operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result_first, _Sent2 __result_last,
|
||||
_Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
|
||||
// TODO: implement
|
||||
(void)__first; (void)__last; (void)__result_first; (void)__result_last; (void)__comp; (void)__proj1; (void)__proj2;
|
||||
return {};
|
||||
auto __result = std::__partial_sort_copy<_RangeAlgPolicy>(
|
||||
std::move(__first), std::move(__last), std::move(__result_first), std::move(__result_last),
|
||||
__comp, __proj1, __proj2
|
||||
);
|
||||
return {std::move(__result.first), std::move(__result.second)};
|
||||
}
|
||||
|
||||
template <input_range _Range1, random_access_range _Range2, class _Comp = ranges::less,
|
||||
@ -67,9 +68,11 @@ struct __fn {
|
||||
partial_sort_copy_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>>
|
||||
operator()(_Range1&& __range, _Range2&& __result_range, _Comp __comp = {},
|
||||
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
|
||||
// TODO: implement
|
||||
(void)__range; (void)__result_range; (void)__comp; (void)__proj1; (void)__proj2;
|
||||
return {};
|
||||
auto __result = std::__partial_sort_copy<_RangeAlgPolicy>(
|
||||
ranges::begin(__range), ranges::end(__range), ranges::begin(__result_range), ranges::end(__result_range),
|
||||
__comp, __proj1, __proj2
|
||||
);
|
||||
return {std::move(__result.first), std::move(__result.second)};
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -44,7 +44,7 @@ struct __fn {
|
||||
template <class _Iter, class _Sent, class _Proj, class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr
|
||||
subrange<__uncvref_t<_Iter>> __partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) {
|
||||
auto&& __projected_pred = ranges::__make_projected_pred(__pred, __proj);
|
||||
auto&& __projected_pred = std::__make_projected(__pred, __proj);
|
||||
auto __result = std::__partition<_RangeAlgPolicy>(
|
||||
std::move(__first), std::move(__last), __projected_pred, __iterator_concept<_Iter>());
|
||||
|
||||
|
@ -46,7 +46,7 @@ struct __fn {
|
||||
auto __last_iter = ranges::next(__first, __last);
|
||||
auto __len = __last_iter - __first;
|
||||
|
||||
auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
|
||||
auto&& __projected_comp = std::__make_projected(__comp, __proj);
|
||||
std::__pop_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp, __len);
|
||||
|
||||
return __last_iter;
|
||||
|
@ -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_RANGES_PREV_PERMUTATION_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_PREV_PERMUTATION_H
|
||||
|
||||
#include <__algorithm/in_found_result.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/make_projected.h>
|
||||
#include <__algorithm/prev_permutation.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/sortable.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/dangling.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _InIter>
|
||||
using prev_permutation_result = in_found_result<_InIter>;
|
||||
|
||||
namespace __prev_permutation {
|
||||
|
||||
struct __fn {
|
||||
|
||||
template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
|
||||
class _Comp = ranges::less, class _Proj = identity>
|
||||
requires sortable<_Iter, _Comp, _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr prev_permutation_result<_Iter>
|
||||
operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
auto __result = std::__prev_permutation<_RangeAlgPolicy>(
|
||||
std::move(__first), std::move(__last), std::__make_projected(__comp, __proj));
|
||||
return {std::move(__result.first), std::move(__result.second)};
|
||||
}
|
||||
|
||||
template <bidirectional_range _Range,
|
||||
class _Comp = ranges::less, class _Proj = identity>
|
||||
requires sortable<iterator_t<_Range>, _Comp, _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr prev_permutation_result<borrowed_iterator_t<_Range>>
|
||||
operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
auto __result = std::__prev_permutation<_RangeAlgPolicy>(
|
||||
ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj));
|
||||
return {std::move(__result.first), std::move(__result.second)};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace __prev_permutation
|
||||
|
||||
inline namespace __cpo {
|
||||
constexpr inline auto prev_permutation = __prev_permutation::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_PREV_PERMUTATION_H
|
@ -45,7 +45,7 @@ struct __fn {
|
||||
_Iter __push_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
|
||||
auto __last_iter = ranges::next(__first, __last);
|
||||
|
||||
auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
|
||||
auto&& __projected_comp = std::__make_projected(__comp, __proj);
|
||||
std::__push_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp);
|
||||
|
||||
return __last_iter;
|
||||
|
@ -10,19 +10,16 @@
|
||||
#define _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H
|
||||
|
||||
#include <__algorithm/in_out_result.h>
|
||||
#include <__algorithm/make_projected.h>
|
||||
#include <__algorithm/remove_copy.h>
|
||||
#include <__algorithm/ranges_remove_copy_if.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/dangling.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
@ -40,32 +37,30 @@ using remove_copy_result = in_out_result<_InIter, _OutIter>;
|
||||
|
||||
namespace __remove_copy {
|
||||
|
||||
struct __fn {
|
||||
struct __fn {
|
||||
template <input_iterator _InIter,
|
||||
sentinel_for<_InIter> _Sent,
|
||||
weakly_incrementable _OutIter,
|
||||
class _Type,
|
||||
class _Proj = identity>
|
||||
requires indirectly_copyable<_InIter, _OutIter> &&
|
||||
indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _Type*>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
|
||||
auto __pred = [&](auto&& __val) { return __value == __val; };
|
||||
return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
|
||||
}
|
||||
|
||||
template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter, class _Type,
|
||||
class _Proj = identity>
|
||||
requires indirectly_copyable<_InIter, _OutIter> &&
|
||||
indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _Type*>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
remove_copy_result<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
|
||||
// TODO: implement
|
||||
(void)__first; (void)__last; (void)__result; (void)__value; (void)__proj;
|
||||
return {};
|
||||
}
|
||||
|
||||
template <input_range _Range, weakly_incrementable _OutIter, class _Type, class _Proj = identity>
|
||||
requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
|
||||
indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
remove_copy_result<borrowed_iterator_t<_Range>, _OutIter>
|
||||
operator()(_Range&& __range, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
|
||||
// TODO: implement
|
||||
(void)__range; (void)__result; (void)__value; (void)__proj;
|
||||
return {};
|
||||
}
|
||||
|
||||
};
|
||||
template <input_range _Range, weakly_incrementable _OutIter, class _Type, class _Proj = identity>
|
||||
requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
|
||||
indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<borrowed_iterator_t<_Range>, _OutIter>
|
||||
operator()(_Range&& __range, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
|
||||
auto __pred = [&](auto&& __val) { return __value == __val; };
|
||||
return ranges::__remove_copy_if_impl(
|
||||
ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __remove_copy
|
||||
|
||||
|
@ -38,33 +38,43 @@ namespace ranges {
|
||||
template <class _InIter, class _OutIter>
|
||||
using remove_copy_if_result = in_out_result<_InIter, _OutIter>;
|
||||
|
||||
template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr in_out_result<_InIter, _OutIter>
|
||||
__remove_copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) {
|
||||
for (; __first != __last; ++__first) {
|
||||
if (!std::invoke(__pred, std::invoke(__proj, *__first))) {
|
||||
*__result = *__first;
|
||||
++__result;
|
||||
}
|
||||
}
|
||||
return {std::move(__first), std::move(__result)};
|
||||
}
|
||||
|
||||
namespace __remove_copy_if {
|
||||
|
||||
struct __fn {
|
||||
struct __fn {
|
||||
template <input_iterator _InIter,
|
||||
sentinel_for<_InIter> _Sent,
|
||||
weakly_incrementable _OutIter,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
|
||||
requires indirectly_copyable<_InIter, _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
|
||||
return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
|
||||
}
|
||||
|
||||
template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter,
|
||||
class _Proj = identity, indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
|
||||
requires indirectly_copyable<_InIter, _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
remove_copy_if_result<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
|
||||
// TODO: implement
|
||||
(void)__first; (void)__last; (void)__result; (void)__pred; (void)__proj;
|
||||
return {};
|
||||
}
|
||||
|
||||
template <input_range _Range, weakly_incrementable _OutIter, class _Proj = identity,
|
||||
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
|
||||
requires indirectly_copyable<iterator_t<_Range>, _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
remove_copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
|
||||
operator()(_Range&& __range, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
|
||||
// TODO: implement
|
||||
(void)__range; (void)__result; (void)__pred; (void)__proj;
|
||||
return {};
|
||||
}
|
||||
|
||||
};
|
||||
template <input_range _Range,
|
||||
weakly_incrementable _OutIter,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
|
||||
requires indirectly_copyable<iterator_t<_Range>, _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
|
||||
operator()(_Range&& __range, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
|
||||
return ranges::__remove_copy_if_impl(
|
||||
ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __remove_copy_if
|
||||
|
||||
|
@ -10,19 +10,16 @@
|
||||
#define _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H
|
||||
|
||||
#include <__algorithm/in_out_result.h>
|
||||
#include <__algorithm/make_projected.h>
|
||||
#include <__algorithm/replace_copy.h>
|
||||
#include <__algorithm/ranges_replace_copy_if.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/dangling.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
@ -40,35 +37,45 @@ using replace_copy_result = in_out_result<_InIter, _OutIter>;
|
||||
|
||||
namespace __replace_copy {
|
||||
|
||||
struct __fn {
|
||||
|
||||
template <input_iterator _InIter, sentinel_for<_InIter> _Sent, class _Type1, class _Type2,
|
||||
output_iterator<const _Type2&> _OutIter, class _Proj = identity>
|
||||
requires indirectly_copyable<_InIter, _OutIter> &&
|
||||
indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _Type1*>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
replace_copy_result<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type1& __old_value, const _Type2& __new_value,
|
||||
struct __fn {
|
||||
template <input_iterator _InIter,
|
||||
sentinel_for<_InIter> _Sent,
|
||||
class _OldType,
|
||||
class _NewType,
|
||||
output_iterator<const _NewType&> _OutIter,
|
||||
class _Proj = identity>
|
||||
requires indirectly_copyable<_InIter, _OutIter> &&
|
||||
indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _OldType*>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<_InIter, _OutIter>
|
||||
operator()(_InIter __first,
|
||||
_Sent __last,
|
||||
_OutIter __result,
|
||||
const _OldType& __old_value,
|
||||
const _NewType& __new_value,
|
||||
_Proj __proj = {}) const {
|
||||
// TODO: implement
|
||||
(void)__first; (void)__last; (void)__result; (void)__old_value; (void)__new_value; (void)__proj;
|
||||
return {};
|
||||
}
|
||||
auto __pred = [&](const auto& __value) { return __value == __old_value; };
|
||||
return ranges::__replace_copy_if_impl(
|
||||
std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj);
|
||||
}
|
||||
|
||||
template <input_range _Range, class _Type1, class _Type2, output_iterator<const _Type2&> _OutIter,
|
||||
class _Proj = identity>
|
||||
requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
|
||||
indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type1*>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
replace_copy_result<borrowed_iterator_t<_Range>, _OutIter>
|
||||
operator()(_Range&& __range, _OutIter __result, const _Type1& __old_value, const _Type2& __new_value,
|
||||
template <input_range _Range,
|
||||
class _OldType,
|
||||
class _NewType,
|
||||
output_iterator<const _NewType&> _OutIter,
|
||||
class _Proj = identity>
|
||||
requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
|
||||
indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _OldType*>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<borrowed_iterator_t<_Range>, _OutIter>
|
||||
operator()(_Range&& __range,
|
||||
_OutIter __result,
|
||||
const _OldType& __old_value,
|
||||
const _NewType& __new_value,
|
||||
_Proj __proj = {}) const {
|
||||
// TODO: implement
|
||||
(void)__range; (void)__result; (void)__old_value; (void)__new_value; (void)__proj;
|
||||
return {};
|
||||
}
|
||||
|
||||
};
|
||||
auto __pred = [&](const auto& __value) { return __value == __old_value; };
|
||||
return ranges::__replace_copy_if_impl(
|
||||
ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __replace_copy
|
||||
|
||||
|
@ -10,19 +10,14 @@
|
||||
#define _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H
|
||||
|
||||
#include <__algorithm/in_out_result.h>
|
||||
#include <__algorithm/make_projected.h>
|
||||
#include <__algorithm/replace_copy_if.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/dangling.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
@ -38,34 +33,51 @@ namespace ranges {
|
||||
template <class _InIter, class _OutIter>
|
||||
using replace_copy_if_result = in_out_result<_InIter, _OutIter>;
|
||||
|
||||
template <class _InIter, class _Sent, class _OutIter, class _Pred, class _Type, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> __replace_copy_if_impl(
|
||||
_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, const _Type& __new_value, _Proj& __proj) {
|
||||
while (__first != __last) {
|
||||
if (std::invoke(__pred, std::invoke(__proj, *__first)))
|
||||
*__result = __new_value;
|
||||
else
|
||||
*__result = *__first;
|
||||
|
||||
++__first;
|
||||
++__result;
|
||||
}
|
||||
|
||||
return {std::move(__first), std::move(__result)};
|
||||
}
|
||||
|
||||
namespace __replace_copy_if {
|
||||
|
||||
struct __fn {
|
||||
struct __fn {
|
||||
template <input_iterator _InIter,
|
||||
sentinel_for<_InIter> _Sent,
|
||||
class _Type,
|
||||
output_iterator<const _Type&> _OutIter,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
|
||||
requires indirectly_copyable<_InIter, _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> operator()(
|
||||
_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {})
|
||||
const {
|
||||
return ranges::__replace_copy_if_impl(
|
||||
std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj);
|
||||
}
|
||||
|
||||
template <input_iterator _InIter, sentinel_for<_InIter> _Sent, class _Type, output_iterator<const _Type&> _OutIter,
|
||||
class _Proj = identity, indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
|
||||
requires indirectly_copyable<_InIter, _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
replace_copy_if_result<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, const _Type& __new_value,
|
||||
_Proj __proj = {}) const {
|
||||
// TODO: implement
|
||||
(void)__first; (void)__last; (void)__result; (void)__pred; (void)__new_value; (void)__proj;
|
||||
return {};
|
||||
}
|
||||
|
||||
template <input_range _Range, class _Type, output_iterator<const _Type&> _OutIter, class _Proj = identity,
|
||||
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
|
||||
requires indirectly_copyable<iterator_t<_Range>, _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
replace_copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
|
||||
operator()(_Range&& __range, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const {
|
||||
// TODO: implement
|
||||
(void)__range; (void)__result; (void)__pred; (void)__new_value; (void)__proj;
|
||||
return {};
|
||||
}
|
||||
|
||||
};
|
||||
template <input_range _Range,
|
||||
class _Type,
|
||||
output_iterator<const _Type&> _OutIter,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
|
||||
requires indirectly_copyable<iterator_t<_Range>, _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
|
||||
operator()(_Range&& __range, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const {
|
||||
return ranges::__replace_copy_if_impl(
|
||||
ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __replace_copy_if
|
||||
|
||||
|
@ -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_RANGES_ROTATE_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_ROTATE_H
|
||||
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/ranges_iterator_concept.h>
|
||||
#include <__algorithm/rotate.h>
|
||||
#include <__config>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/permutable.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/subrange.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __rotate {
|
||||
|
||||
struct __fn {
|
||||
|
||||
template <class _Iter, class _Sent>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
static subrange<_Iter> __rotate_fn_impl(_Iter __first, _Iter __middle, _Sent __last) {
|
||||
auto __ret = std::__rotate<_RangeAlgPolicy>(
|
||||
std::move(__first), std::move(__middle), std::move(__last));
|
||||
return {std::move(__ret.first), std::move(__ret.second)};
|
||||
}
|
||||
|
||||
template <permutable _Iter, sentinel_for<_Iter> _Sent>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
subrange<_Iter> operator()(_Iter __first, _Iter __middle, _Sent __last) const {
|
||||
return __rotate_fn_impl(std::move(__first), std::move(__middle), std::move(__last));
|
||||
}
|
||||
|
||||
template <forward_range _Range>
|
||||
requires permutable<iterator_t<_Range>>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
borrowed_subrange_t<_Range> operator()(_Range&& __range, iterator_t<_Range> __middle) const {
|
||||
return __rotate_fn_impl(ranges::begin(__range), std::move(__middle), ranges::end(__range));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace __rotate
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto rotate = __rotate::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_H
|
@ -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_RANGES_SAMPLE_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_SAMPLE_H
|
||||
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/sample.h>
|
||||
#include <__algorithm/uniform_random_bit_generator_adaptor.h>
|
||||
#include <__config>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/incrementable_traits.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__random/uniform_random_bit_generator.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/move.h>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __sample {
|
||||
|
||||
struct __fn {
|
||||
|
||||
template <input_iterator _Iter, sentinel_for<_Iter> _Sent, weakly_incrementable _OutIter, class _Gen>
|
||||
requires (forward_iterator<_Iter> || random_access_iterator<_OutIter>) &&
|
||||
indirectly_copyable<_Iter, _OutIter> &&
|
||||
uniform_random_bit_generator<remove_reference_t<_Gen>>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_OutIter operator()(_Iter __first, _Sent __last,
|
||||
_OutIter __out_first, iter_difference_t<_Iter> __n, _Gen&& __gen) const {
|
||||
_ClassicGenAdaptor<_Gen> __adapted_gen(__gen);
|
||||
return std::__sample<_RangeAlgPolicy>(
|
||||
std::move(__first), std::move(__last), std::move(__out_first), __n, __adapted_gen);
|
||||
}
|
||||
|
||||
template <input_range _Range, weakly_incrementable _OutIter, class _Gen>
|
||||
requires (forward_range<_Range> || random_access_iterator<_OutIter>) &&
|
||||
indirectly_copyable<iterator_t<_Range>, _OutIter> &&
|
||||
uniform_random_bit_generator<remove_reference_t<_Gen>>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_OutIter operator()(_Range&& __range, _OutIter __out_first, range_difference_t<_Range> __n, _Gen&& __gen) const {
|
||||
return (*this)(ranges::begin(__range), ranges::end(__range),
|
||||
std::move(__out_first), __n, std::forward<_Gen>(__gen));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace __sample
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto sample = __sample::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_SAMPLE_H
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/shuffle.h>
|
||||
#include <__algorithm/uniform_random_bit_generator_adaptor.h>
|
||||
#include <__config>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
@ -32,43 +33,12 @@
|
||||
|
||||
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __shuffle {
|
||||
|
||||
struct __fn {
|
||||
// `std::shuffle` is more constrained than `std::ranges::shuffle`. `std::ranges::shuffle` only requires the given
|
||||
// generator to satisfy the `std::uniform_random_bit_generator` concept. `std::shuffle` requires the given
|
||||
// generator to meet the uniform random bit generator requirements; these requirements include satisfying
|
||||
// `std::uniform_random_bit_generator` and add a requirement for the generator to provide a nested `result_type`
|
||||
// typedef (see `[rand.req.urng]`).
|
||||
//
|
||||
// To reuse the implementation from `std::shuffle`, make the given generator meet the classic requirements by wrapping
|
||||
// it into an adaptor type that forwards all of its interface and adds the required typedef.
|
||||
template <class _Gen>
|
||||
class _ClassicGenAdaptor {
|
||||
private:
|
||||
// The generator is not required to be copyable or movable, so it has to be stored as a reference.
|
||||
_Gen& __gen;
|
||||
|
||||
public:
|
||||
using result_type = invoke_result_t<_Gen&>;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
static constexpr auto min() { return __uncvref_t<_Gen>::min(); }
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
static constexpr auto max() { return __uncvref_t<_Gen>::max(); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit _ClassicGenAdaptor(_Gen& __g) : __gen(__g) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()() const { return __gen(); }
|
||||
};
|
||||
|
||||
template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Gen>
|
||||
requires permutable<_Iter> && uniform_random_bit_generator<remove_reference_t<_Gen>>
|
||||
@ -96,8 +66,6 @@ inline namespace __cpo {
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H
|
||||
|
@ -44,7 +44,7 @@ struct __fn {
|
||||
_Iter __sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
|
||||
auto __last_iter = ranges::next(__first, __last);
|
||||
|
||||
auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
|
||||
auto&& __projected_comp = std::__make_projected(__comp, __proj);
|
||||
std::__sort_impl<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp);
|
||||
|
||||
return __last_iter;
|
||||
|
@ -45,7 +45,7 @@ struct __fn {
|
||||
_Iter __sort_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
|
||||
auto __last_iter = ranges::next(__first, __last);
|
||||
|
||||
auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
|
||||
auto&& __projected_comp = std::__make_projected(__comp, __proj);
|
||||
std::__sort_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp);
|
||||
|
||||
return __last_iter;
|
||||
|
@ -49,7 +49,7 @@ struct __fn {
|
||||
_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) {
|
||||
auto __last_iter = ranges::next(__first, __last);
|
||||
|
||||
auto&& __projected_pred = ranges::__make_projected_pred(__pred, __proj);
|
||||
auto&& __projected_pred = std::__make_projected(__pred, __proj);
|
||||
auto __result = std::__stable_partition<_RangeAlgPolicy>(
|
||||
std::move(__first), __last_iter, __projected_pred, __iterator_concept<_Iter>());
|
||||
|
||||
|
@ -44,7 +44,7 @@ struct __fn {
|
||||
static _Iter __stable_sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
|
||||
auto __last_iter = ranges::next(__first, __last);
|
||||
|
||||
auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
|
||||
auto&& __projected_comp = std::__make_projected(__comp, __proj);
|
||||
std::__stable_sort_impl<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp);
|
||||
|
||||
return __last_iter;
|
||||
|
@ -10,6 +10,8 @@
|
||||
#define _LIBCPP___ALGORITHM_RANGES_SWAP_RANGES_H
|
||||
|
||||
#include <__algorithm/in_in_result.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/swap_ranges.h>
|
||||
#include <__config>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/iter_swap.h>
|
||||
@ -38,12 +40,9 @@ struct __fn {
|
||||
requires indirectly_swappable<_I1, _I2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr swap_ranges_result<_I1, _I2>
|
||||
operator()(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2) const {
|
||||
while (__first1 != __last1 && __first2 != __last2) {
|
||||
ranges::iter_swap(__first1, __first2);
|
||||
++__first1;
|
||||
++__first2;
|
||||
}
|
||||
return {_VSTD::move(__first1), _VSTD::move(__first2)};
|
||||
auto __ret = std::__swap_ranges<_RangeAlgPolicy>(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2));
|
||||
return {std::move(__ret.first), std::move(__ret.second)};
|
||||
}
|
||||
|
||||
template <input_range _R1, input_range _R2>
|
||||
|
@ -9,6 +9,7 @@
|
||||
#ifndef _LIBCPP___ALGORITHM_RANGES_UNIQUE_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_UNIQUE_H
|
||||
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/make_projected.h>
|
||||
#include <__algorithm/unique.h>
|
||||
#include <__config>
|
||||
@ -37,28 +38,31 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
namespace ranges {
|
||||
namespace __unique {
|
||||
|
||||
struct __fn {
|
||||
struct __fn {
|
||||
template <
|
||||
permutable _Iter,
|
||||
sentinel_for<_Iter> _Sent,
|
||||
class _Proj = identity,
|
||||
indirect_equivalence_relation<projected<_Iter, _Proj>> _Comp = ranges::equal_to>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
|
||||
operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
auto __ret = std::__unique<_RangeAlgPolicy>(
|
||||
std::move(__first), std::move(__last), std::__make_projected(__comp, __proj));
|
||||
return {std::move(__ret.first), std::move(__ret.second)};
|
||||
}
|
||||
|
||||
template <permutable _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
|
||||
indirect_equivalence_relation<projected<_Iter, _Proj>> _Comp = ranges::equal_to>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
subrange<_Iter> operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
// TODO: implement
|
||||
(void)__first; (void)__last; (void)__comp; (void)__proj;
|
||||
return {};
|
||||
}
|
||||
|
||||
template <forward_range _Range, class _Proj = identity,
|
||||
indirect_equivalence_relation<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
|
||||
requires permutable<iterator_t<_Range>>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
borrowed_subrange_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
// TODO: implement
|
||||
(void)__range; (void)__comp; (void)__proj;
|
||||
return {};
|
||||
}
|
||||
|
||||
};
|
||||
template <
|
||||
forward_range _Range,
|
||||
class _Proj = identity,
|
||||
indirect_equivalence_relation<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
|
||||
requires permutable<iterator_t<_Range>>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
|
||||
operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
auto __ret = std::__unique<_RangeAlgPolicy>(
|
||||
ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj));
|
||||
return {std::move(__ret.first), std::move(__ret.second)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __unique
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H
|
||||
|
||||
#include <__algorithm/in_out_result.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/make_projected.h>
|
||||
#include <__algorithm/unique_copy.h>
|
||||
#include <__concepts/same_as.h>
|
||||
@ -19,8 +20,8 @@
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/readable_traits.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__iterator/readable_traits.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/dangling.h>
|
||||
@ -42,42 +43,68 @@ using unique_copy_result = in_out_result<_InIter, _OutIter>;
|
||||
|
||||
namespace __unique_copy {
|
||||
|
||||
template <class _InIter, class _OutIter>
|
||||
concept __can_reread_from_output = (input_iterator<_OutIter> && same_as<iter_value_t<_InIter>, iter_value_t<_OutIter>>);
|
||||
|
||||
struct __fn {
|
||||
template <class _InIter, class _OutIter>
|
||||
static consteval auto __get_algo_tag() {
|
||||
if constexpr (forward_iterator<_InIter>) {
|
||||
return __unique_copy_tags::__reread_from_input_tag{};
|
||||
} else if constexpr (__can_reread_from_output<_InIter, _OutIter>) {
|
||||
return __unique_copy_tags::__reread_from_output_tag{};
|
||||
} else if constexpr (indirectly_copyable_storable<_InIter, _OutIter>) {
|
||||
return __unique_copy_tags::__read_from_tmp_value_tag{};
|
||||
}
|
||||
}
|
||||
|
||||
template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter, class _Proj = identity,
|
||||
template <class _InIter, class _OutIter>
|
||||
using __algo_tag_t = decltype(__get_algo_tag<_InIter, _OutIter>());
|
||||
|
||||
template <input_iterator _InIter,
|
||||
sentinel_for<_InIter> _Sent,
|
||||
weakly_incrementable _OutIter,
|
||||
class _Proj = identity,
|
||||
indirect_equivalence_relation<projected<_InIter, _Proj>> _Comp = ranges::equal_to>
|
||||
requires indirectly_copyable<_InIter, _OutIter> &&
|
||||
(forward_iterator<_InIter> ||
|
||||
(input_iterator<_OutIter> && same_as<iter_value_t<_InIter>, iter_value_t<_OutIter>>) ||
|
||||
indirectly_copyable_storable<_InIter, _OutIter>)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
unique_copy_result<_InIter, _OutIter>
|
||||
requires indirectly_copyable<_InIter, _OutIter> &&
|
||||
(forward_iterator<_InIter> ||
|
||||
(input_iterator<_OutIter> && same_as<iter_value_t<_InIter>, iter_value_t<_OutIter>>) ||
|
||||
indirectly_copyable_storable<_InIter, _OutIter>)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr unique_copy_result<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
// TODO: implement
|
||||
(void)__first; (void)__last; (void)__result; (void)__comp; (void)__proj;
|
||||
return {};
|
||||
auto __ret = std::__unique_copy<_RangeAlgPolicy>(
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
std::move(__result),
|
||||
std::__make_projected(__comp, __proj),
|
||||
__algo_tag_t<_InIter, _OutIter>());
|
||||
return {std::move(__ret.first), std::move(__ret.second)};
|
||||
}
|
||||
|
||||
template <input_range _Range, weakly_incrementable _OutIter, class _Proj = identity,
|
||||
template <input_range _Range,
|
||||
weakly_incrementable _OutIter,
|
||||
class _Proj = identity,
|
||||
indirect_equivalence_relation<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
|
||||
requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
|
||||
(forward_iterator<iterator_t<_Range>> ||
|
||||
(input_iterator<_OutIter> && same_as<range_value_t<_Range>, iter_value_t<_OutIter>>) ||
|
||||
indirectly_copyable_storable<iterator_t<_Range>, _OutIter>)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
unique_copy_result<borrowed_iterator_t<_Range>, _OutIter>
|
||||
requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
|
||||
(forward_iterator<iterator_t<_Range>> ||
|
||||
(input_iterator<_OutIter> && same_as<range_value_t<_Range>, iter_value_t<_OutIter>>) ||
|
||||
indirectly_copyable_storable<iterator_t<_Range>, _OutIter>)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr unique_copy_result<borrowed_iterator_t<_Range>, _OutIter>
|
||||
operator()(_Range&& __range, _OutIter __result, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
// TODO: implement
|
||||
(void)__range; (void)__result; (void)__comp; (void)__proj;
|
||||
return {};
|
||||
auto __ret = std::__unique_copy<_RangeAlgPolicy>(
|
||||
ranges::begin(__range),
|
||||
ranges::end(__range),
|
||||
std::move(__result),
|
||||
std::__make_projected(__comp, __proj),
|
||||
__algo_tag_t<iterator_t<_Range>, _OutIter>());
|
||||
return {std::move(__ret.first), std::move(__ret.second)};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace __unique_copy
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto unique_copy = __unique_copy::__fn{};
|
||||
inline constexpr auto unique_copy = __unique_copy::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
|
@ -10,8 +10,10 @@
|
||||
#define _LIBCPP___ALGORITHM_REVERSE_H
|
||||
|
||||
#include <__algorithm/iter_swap.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
|
||||
@ -19,28 +21,35 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _BidirectionalIterator>
|
||||
template <class _AlgPolicy, class _BidirectionalIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
__reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag)
|
||||
__reverse_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag)
|
||||
{
|
||||
while (__first != __last)
|
||||
{
|
||||
if (__first == --__last)
|
||||
break;
|
||||
_VSTD::iter_swap(__first, __last);
|
||||
_IterOps<_AlgPolicy>::iter_swap(__first, __last);
|
||||
++__first;
|
||||
}
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator>
|
||||
template <class _AlgPolicy, class _RandomAccessIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
__reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag)
|
||||
__reverse_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag)
|
||||
{
|
||||
if (__first != __last)
|
||||
for (; __first < --__last; ++__first)
|
||||
_VSTD::iter_swap(__first, __last);
|
||||
_IterOps<_AlgPolicy>::iter_swap(__first, __last);
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _BidirectionalIterator, class _Sentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void __reverse(_BidirectionalIterator __first, _Sentinel __last) {
|
||||
using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_BidirectionalIterator>;
|
||||
std::__reverse_impl<_AlgPolicy>(std::move(__first), std::move(__last), _IterCategory());
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator>
|
||||
@ -48,7 +57,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
|
||||
{
|
||||
_VSTD::__reverse(__first, __last, typename iterator_traits<_BidirectionalIterator>::iterator_category());
|
||||
std::__reverse<_ClassicAlgPolicy>(std::move(__first), std::move(__last));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
@ -15,10 +15,8 @@
|
||||
#include <__algorithm/swap_ranges.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/next.h>
|
||||
#include <__iterator/prev.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/swap.h>
|
||||
#include <__utility/pair.h>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
@ -32,9 +30,11 @@ _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
|
||||
__rotate_left(_ForwardIterator __first, _ForwardIterator __last)
|
||||
{
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
|
||||
value_type __tmp = _IterOps<_AlgPolicy>::__iter_move(__first);
|
||||
// TODO(ranges): pass `_AlgPolicy` to `move`.
|
||||
_ForwardIterator __lm1 = _VSTD::move(_VSTD::next(__first), __last, __first);
|
||||
using _Ops = _IterOps<_AlgPolicy>;
|
||||
|
||||
value_type __tmp = _Ops::__iter_move(__first);
|
||||
_ForwardIterator __lm1 = std::__move<_AlgPolicy>(
|
||||
_Ops::next(__first), __last, __first).second;
|
||||
*__lm1 = _VSTD::move(__tmp);
|
||||
return __lm1;
|
||||
}
|
||||
@ -44,11 +44,11 @@ _LIBCPP_CONSTEXPR_AFTER_CXX11 _BidirectionalIterator
|
||||
__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last)
|
||||
{
|
||||
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
|
||||
// TODO(ranges): pass `_AlgPolicy` to `prev`.
|
||||
_BidirectionalIterator __lm1 = _VSTD::prev(__last);
|
||||
value_type __tmp = _IterOps<_AlgPolicy>::__iter_move(__lm1);
|
||||
// TODO(ranges): pass `_AlgPolicy` to `move_backward`.
|
||||
_BidirectionalIterator __fp1 = _VSTD::move_backward(__first, __lm1, __last);
|
||||
using _Ops = _IterOps<_AlgPolicy>;
|
||||
|
||||
_BidirectionalIterator __lm1 = _Ops::prev(__last);
|
||||
value_type __tmp = _Ops::__iter_move(__lm1);
|
||||
_BidirectionalIterator __fp1 = std::__move_backward<_AlgPolicy>(__first, __lm1, std::move(__last));
|
||||
*__first = _VSTD::move(__tmp);
|
||||
return __fp1;
|
||||
}
|
||||
@ -108,26 +108,26 @@ __rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Ran
|
||||
{
|
||||
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
|
||||
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
|
||||
using _Ops = _IterOps<_AlgPolicy>;
|
||||
|
||||
const difference_type __m1 = __middle - __first;
|
||||
const difference_type __m2 = __last - __middle;
|
||||
const difference_type __m2 = _Ops::distance(__middle, __last);
|
||||
if (__m1 == __m2)
|
||||
{
|
||||
// TODO(ranges): pass `_AlgPolicy` to `swap_ranges`.
|
||||
_VSTD::swap_ranges(__first, __middle, __middle);
|
||||
std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle, __last);
|
||||
return __middle;
|
||||
}
|
||||
const difference_type __g = _VSTD::__algo_gcd(__m1, __m2);
|
||||
for (_RandomAccessIterator __p = __first + __g; __p != __first;)
|
||||
{
|
||||
value_type __t(_IterOps<_AlgPolicy>::__iter_move(--__p));
|
||||
value_type __t(_Ops::__iter_move(--__p));
|
||||
_RandomAccessIterator __p1 = __p;
|
||||
_RandomAccessIterator __p2 = __p1 + __m1;
|
||||
do
|
||||
{
|
||||
*__p1 = _IterOps<_AlgPolicy>::__iter_move(__p2);
|
||||
*__p1 = _Ops::__iter_move(__p2);
|
||||
__p1 = __p2;
|
||||
const difference_type __d = __last - __p2;
|
||||
const difference_type __d = _Ops::distance(__p2, __last);
|
||||
if (__m1 < __d)
|
||||
__p2 += __m1;
|
||||
else
|
||||
@ -188,16 +188,23 @@ __rotate_impl(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Ra
|
||||
return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _RandomAccessIterator, class _IterCategory>
|
||||
template <class _AlgPolicy, class _Iterator, class _Sentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
_RandomAccessIterator __rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle,
|
||||
_RandomAccessIterator __last, _IterCategory __iter_category) {
|
||||
if (__first == __middle)
|
||||
return __last;
|
||||
if (__middle == __last)
|
||||
return __first;
|
||||
pair<_Iterator, _Iterator>
|
||||
__rotate(_Iterator __first, _Iterator __middle, _Sentinel __last) {
|
||||
using _Ret = pair<_Iterator, _Iterator>;
|
||||
_Iterator __last_iter = _IterOps<_AlgPolicy>::next(__middle, __last);
|
||||
|
||||
return std::__rotate_impl<_AlgPolicy>(std::move(__first), std::move(__middle), std::move(__last), __iter_category);
|
||||
if (__first == __middle)
|
||||
return _Ret(__last_iter, __last_iter);
|
||||
if (__middle == __last)
|
||||
return _Ret(std::move(__first), std::move(__last_iter));
|
||||
|
||||
using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_Iterator>;
|
||||
auto __result = std::__rotate_impl<_AlgPolicy>(
|
||||
std::move(__first), std::move(__middle), __last_iter, _IterCategory());
|
||||
|
||||
return _Ret(std::move(__result), std::move(__last_iter));
|
||||
}
|
||||
|
||||
template <class _ForwardIterator>
|
||||
@ -205,8 +212,8 @@ inline _LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
|
||||
rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
|
||||
{
|
||||
return std::__rotate<_ClassicAlgPolicy>(__first, __middle, __last,
|
||||
typename iterator_traits<_ForwardIterator>::iterator_category());
|
||||
return std::__rotate<_ClassicAlgPolicy>(
|
||||
std::move(__first), std::move(__middle), std::move(__last)).first;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
@ -9,12 +9,14 @@
|
||||
#ifndef _LIBCPP___ALGORITHM_SAMPLE_H
|
||||
#define _LIBCPP___ALGORITHM_SAMPLE_H
|
||||
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/min.h>
|
||||
#include <__assert>
|
||||
#include <__config>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__random/uniform_int_distribution.h>
|
||||
#include <__utility/move.h>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
@ -26,13 +28,14 @@ _LIBCPP_PUSH_MACROS
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _PopulationIterator, class _SampleIterator, class _Distance,
|
||||
template <class _AlgPolicy,
|
||||
class _PopulationIterator, class _PopulationSentinel, class _SampleIterator, class _Distance,
|
||||
class _UniformRandomNumberGenerator>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_SampleIterator __sample(_PopulationIterator __first,
|
||||
_PopulationIterator __last, _SampleIterator __output_iter,
|
||||
_PopulationSentinel __last, _SampleIterator __output_iter,
|
||||
_Distance __n,
|
||||
_UniformRandomNumberGenerator & __g,
|
||||
_UniformRandomNumberGenerator& __g,
|
||||
input_iterator_tag) {
|
||||
|
||||
_Distance __k = 0;
|
||||
@ -47,15 +50,16 @@ _SampleIterator __sample(_PopulationIterator __first,
|
||||
return __output_iter + _VSTD::min(__n, __k);
|
||||
}
|
||||
|
||||
template <class _PopulationIterator, class _SampleIterator, class _Distance,
|
||||
template <class _AlgPolicy,
|
||||
class _PopulationIterator, class _PopulationSentinel, class _SampleIterator, class _Distance,
|
||||
class _UniformRandomNumberGenerator>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_SampleIterator __sample(_PopulationIterator __first,
|
||||
_PopulationIterator __last, _SampleIterator __output_iter,
|
||||
_PopulationSentinel __last, _SampleIterator __output_iter,
|
||||
_Distance __n,
|
||||
_UniformRandomNumberGenerator& __g,
|
||||
forward_iterator_tag) {
|
||||
_Distance __unsampled_sz = _VSTD::distance(__first, __last);
|
||||
_Distance __unsampled_sz = _IterOps<_AlgPolicy>::distance(__first, __last);
|
||||
for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) {
|
||||
_Distance __r = uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g);
|
||||
if (__r < __n) {
|
||||
@ -66,24 +70,22 @@ _SampleIterator __sample(_PopulationIterator __first,
|
||||
return __output_iter;
|
||||
}
|
||||
|
||||
template <class _PopulationIterator, class _SampleIterator, class _Distance,
|
||||
template <class _AlgPolicy,
|
||||
class _PopulationIterator, class _PopulationSentinel, class _SampleIterator, class _Distance,
|
||||
class _UniformRandomNumberGenerator>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_SampleIterator __sample(_PopulationIterator __first,
|
||||
_PopulationIterator __last, _SampleIterator __output_iter,
|
||||
_PopulationSentinel __last, _SampleIterator __output_iter,
|
||||
_Distance __n, _UniformRandomNumberGenerator& __g) {
|
||||
typedef typename iterator_traits<_PopulationIterator>::iterator_category
|
||||
_PopCategory;
|
||||
typedef typename iterator_traits<_PopulationIterator>::difference_type
|
||||
_Difference;
|
||||
static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value ||
|
||||
__is_cpp17_random_access_iterator<_SampleIterator>::value,
|
||||
"SampleIterator must meet the requirements of RandomAccessIterator");
|
||||
typedef typename common_type<_Distance, _Difference>::type _CommonType;
|
||||
_LIBCPP_ASSERT(__n >= 0, "N must be a positive number.");
|
||||
return _VSTD::__sample(
|
||||
__first, __last, __output_iter, _CommonType(__n),
|
||||
__g, _PopCategory());
|
||||
|
||||
using _PopIterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_PopulationIterator>;
|
||||
using _Difference = typename _IterOps<_AlgPolicy>::template __difference_type<_PopulationIterator>;
|
||||
using _CommonType = typename common_type<_Distance, _Difference>::type;
|
||||
|
||||
return std::__sample<_AlgPolicy>(
|
||||
std::move(__first), std::move(__last), std::move(__output_iter), _CommonType(__n),
|
||||
__g, _PopIterCategory());
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
@ -93,8 +95,14 @@ inline _LIBCPP_INLINE_VISIBILITY
|
||||
_SampleIterator sample(_PopulationIterator __first,
|
||||
_PopulationIterator __last, _SampleIterator __output_iter,
|
||||
_Distance __n, _UniformRandomNumberGenerator&& __g) {
|
||||
return _VSTD::__sample(__first, __last, __output_iter, __n, __g);
|
||||
static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value ||
|
||||
__is_cpp17_random_access_iterator<_SampleIterator>::value,
|
||||
"SampleIterator must meet the requirements of RandomAccessIterator");
|
||||
|
||||
return std::__sample<_ClassicAlgPolicy>(
|
||||
std::move(__first), std::move(__last), std::move(__output_iter), __n, __g);
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 14
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX11 void
|
||||
__sift_down(_RandomAccessIterator __first, _Compare __comp,
|
||||
__sift_down(_RandomAccessIterator __first, _Compare&& __comp,
|
||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len,
|
||||
_RandomAccessIterator __start)
|
||||
{
|
||||
@ -79,7 +79,7 @@ __sift_down(_RandomAccessIterator __first, _Compare __comp,
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator
|
||||
__floyd_sift_down(_RandomAccessIterator __first, _Compare __comp,
|
||||
__floyd_sift_down(_RandomAccessIterator __first, _Compare&& __comp,
|
||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len)
|
||||
{
|
||||
using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
|
||||
|
@ -26,13 +26,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) {
|
||||
void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) {
|
||||
using _CompRef = typename __comp_ref_type<_Compare>::type;
|
||||
_CompRef __comp_ref = __comp;
|
||||
|
||||
using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
|
||||
for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n)
|
||||
std::__pop_heap<_AlgPolicy, _CompRef>(__first, __last, __comp_ref, __n);
|
||||
std::__pop_heap<_AlgPolicy>(__first, __last, __comp_ref, __n);
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
|
@ -108,7 +108,7 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred
|
||||
__second_half_done:
|
||||
// TTTFFFFFTTTTTFFFFF
|
||||
// f ff m sf l
|
||||
return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false, __fit);
|
||||
return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first;
|
||||
// TTTTTTTTFFFFFFFFFF
|
||||
// |
|
||||
}
|
||||
@ -253,7 +253,7 @@ __stable_partition_impl(_BidirectionalIterator __first, _BidirectionalIterator _
|
||||
__second_half_done:
|
||||
// TTTFFFFFTTTTTFFFFF
|
||||
// f ff m sf l
|
||||
return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false, __bit);
|
||||
return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first;
|
||||
// TTTTTTTTFFFFFFFFFF
|
||||
// |
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp
|
||||
}
|
||||
std::__stable_sort<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff, __buff_size);
|
||||
std::__stable_sort<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size);
|
||||
std::__inplace_merge<_AlgPolicy, _Compare>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size);
|
||||
std::__inplace_merge<_AlgPolicy>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size);
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
|
||||
|
@ -9,8 +9,10 @@
|
||||
#ifndef _LIBCPP___ALGORITHM_SWAP_RANGES_H
|
||||
#define _LIBCPP___ALGORITHM_SWAP_RANGES_H
|
||||
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__utility/swap.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
@ -18,12 +20,39 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// 2+2 iterators: the shorter size will be used.
|
||||
template <class _AlgPolicy, class _ForwardIterator1, class _Sentinel1, class _ForwardIterator2, class _Sentinel2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
pair<_ForwardIterator1, _ForwardIterator2>
|
||||
__swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, _Sentinel2 __last2) {
|
||||
while (__first1 != __last1 && __first2 != __last2) {
|
||||
_IterOps<_AlgPolicy>::iter_swap(__first1, __first2);
|
||||
++__first1;
|
||||
++__first2;
|
||||
}
|
||||
|
||||
return pair<_ForwardIterator1, _ForwardIterator2>(std::move(__first1), std::move(__first2));
|
||||
}
|
||||
|
||||
// 2+1 iterators: size2 >= size1.
|
||||
template <class _AlgPolicy, class _ForwardIterator1, class _Sentinel1, class _ForwardIterator2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
pair<_ForwardIterator1, _ForwardIterator2>
|
||||
__swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2) {
|
||||
while (__first1 != __last1) {
|
||||
_IterOps<_AlgPolicy>::iter_swap(__first1, __first2);
|
||||
++__first1;
|
||||
++__first2;
|
||||
}
|
||||
|
||||
return pair<_ForwardIterator1, _ForwardIterator2>(std::move(__first1), std::move(__first2));
|
||||
}
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator2
|
||||
swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
|
||||
for (; __first1 != __last1; ++__first1, (void)++__first2)
|
||||
swap(*__first1, *__first2);
|
||||
return __first2;
|
||||
return std::__swap_ranges<_ClassicAlgPolicy>(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2)).second;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
@ -0,0 +1,62 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H
|
||||
|
||||
#include <__config>
|
||||
#include <__functional/invoke.h>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// Range versions of random algorithms (e.g. `std::shuffle`) are less constrained than their classic counterparts.
|
||||
// Range algorithms only require the given generator to satisfy the `std::uniform_random_bit_generator` concept.
|
||||
// Classic algorithms require the given generator to meet the uniform random bit generator requirements; these
|
||||
// requirements include satisfying `std::uniform_random_bit_generator` and add a requirement for the generator to
|
||||
// provide a nested `result_type` typedef (see `[rand.req.urng]`).
|
||||
//
|
||||
// To be able to reuse classic implementations, make the given generator meet the classic requirements by wrapping
|
||||
// it into an adaptor type that forwards all of its interface and adds the required typedef.
|
||||
template <class _Gen>
|
||||
class _ClassicGenAdaptor {
|
||||
private:
|
||||
// The generator is not required to be copyable or movable, so it has to be stored as a reference.
|
||||
_Gen& __gen;
|
||||
|
||||
public:
|
||||
using result_type = invoke_result_t<_Gen&>;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
static constexpr auto min() { return __uncvref_t<_Gen>::min(); }
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
static constexpr auto max() { return __uncvref_t<_Gen>::max(); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit _ClassicGenAdaptor(_Gen& __g) : __gen(__g) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()() const { return __gen(); }
|
||||
};
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H
|
@ -11,9 +11,11 @@
|
||||
|
||||
#include <__algorithm/adjacent_find.h>
|
||||
#include <__algorithm/comp.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
|
||||
@ -23,32 +25,34 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// unique
|
||||
|
||||
template <class _AlgPolicy, class _Iter, class _Sent, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 std::pair<_Iter, _Iter>
|
||||
__unique(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) {
|
||||
__first = std::__adjacent_find(__first, __last, __pred);
|
||||
if (__first != __last) {
|
||||
// ... a a ? ...
|
||||
// f i
|
||||
_Iter __i = __first;
|
||||
for (++__i; ++__i != __last;)
|
||||
if (!__pred(*__first, *__i))
|
||||
*++__first = _IterOps<_AlgPolicy>::__iter_move(__i);
|
||||
++__first;
|
||||
return std::pair<_Iter, _Iter>(std::move(__first), std::move(__i));
|
||||
}
|
||||
return std::pair<_Iter, _Iter>(__first, __first);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
|
||||
unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)
|
||||
{
|
||||
__first = _VSTD::adjacent_find<_ForwardIterator, _BinaryPredicate&>(__first, __last, __pred);
|
||||
if (__first != __last)
|
||||
{
|
||||
// ... a a ? ...
|
||||
// f i
|
||||
_ForwardIterator __i = __first;
|
||||
for (++__i; ++__i != __last;)
|
||||
if (!__pred(*__first, *__i))
|
||||
*++__first = _VSTD::move(*__i);
|
||||
++__first;
|
||||
}
|
||||
return __first;
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
|
||||
unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) {
|
||||
return std::__unique<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred).first;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
_ForwardIterator
|
||||
unique(_ForwardIterator __first, _ForwardIterator __last)
|
||||
{
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type __v;
|
||||
return _VSTD::unique(__first, __last, __equal_to<__v>());
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
|
||||
unique(_ForwardIterator __first, _ForwardIterator __last) {
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type __v;
|
||||
return std::unique(__first, __last, __equal_to<__v>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
@ -10,8 +10,14 @@
|
||||
#define _LIBCPP___ALGORITHM_UNIQUE_COPY_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/conditional.h>
|
||||
#include <__type_traits/is_base_of.h>
|
||||
#include <__type_traits/is_same.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
@ -19,88 +25,99 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _BinaryPredicate, class _InputIterator, class _OutputIterator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
|
||||
__unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred,
|
||||
input_iterator_tag, output_iterator_tag)
|
||||
{
|
||||
if (__first != __last)
|
||||
{
|
||||
typename iterator_traits<_InputIterator>::value_type __t(*__first);
|
||||
namespace __unique_copy_tags {
|
||||
|
||||
struct __reread_from_input_tag {};
|
||||
struct __reread_from_output_tag {};
|
||||
struct __read_from_tmp_value_tag {};
|
||||
|
||||
} // namespace __unique_copy_tags
|
||||
|
||||
template <class _AlgPolicy, class _BinaryPredicate, class _InputIterator, class _Sent, class _OutputIterator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _OutputIterator>
|
||||
__unique_copy(_InputIterator __first,
|
||||
_Sent __last,
|
||||
_OutputIterator __result,
|
||||
_BinaryPredicate&& __pred,
|
||||
__unique_copy_tags::__read_from_tmp_value_tag) {
|
||||
if (__first != __last) {
|
||||
typename _IterOps<_AlgPolicy>::template __value_type<_InputIterator> __t(*__first);
|
||||
*__result = __t;
|
||||
++__result;
|
||||
while (++__first != __last) {
|
||||
if (!__pred(__t, *__first)) {
|
||||
__t = *__first;
|
||||
*__result = __t;
|
||||
++__result;
|
||||
while (++__first != __last)
|
||||
{
|
||||
if (!__pred(__t, *__first))
|
||||
{
|
||||
__t = *__first;
|
||||
*__result = __t;
|
||||
++__result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return __result;
|
||||
}
|
||||
return pair<_InputIterator, _OutputIterator>(std::move(__first), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _BinaryPredicate, class _ForwardIterator, class _OutputIterator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
|
||||
__unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred,
|
||||
forward_iterator_tag, output_iterator_tag)
|
||||
{
|
||||
if (__first != __last)
|
||||
{
|
||||
_ForwardIterator __i = __first;
|
||||
*__result = *__i;
|
||||
++__result;
|
||||
while (++__first != __last)
|
||||
{
|
||||
if (!__pred(*__i, *__first))
|
||||
{
|
||||
*__result = *__first;
|
||||
++__result;
|
||||
__i = __first;
|
||||
}
|
||||
}
|
||||
}
|
||||
return __result;
|
||||
}
|
||||
|
||||
template <class _BinaryPredicate, class _InputIterator, class _ForwardIterator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
|
||||
__unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred,
|
||||
input_iterator_tag, forward_iterator_tag)
|
||||
{
|
||||
if (__first != __last)
|
||||
{
|
||||
template <class _AlgPolicy, class _BinaryPredicate, class _ForwardIterator, class _Sent, class _OutputIterator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI pair<_ForwardIterator, _OutputIterator>
|
||||
__unique_copy(_ForwardIterator __first,
|
||||
_Sent __last,
|
||||
_OutputIterator __result,
|
||||
_BinaryPredicate&& __pred,
|
||||
__unique_copy_tags::__reread_from_input_tag) {
|
||||
if (__first != __last) {
|
||||
_ForwardIterator __i = __first;
|
||||
*__result = *__i;
|
||||
++__result;
|
||||
while (++__first != __last) {
|
||||
if (!__pred(*__i, *__first)) {
|
||||
*__result = *__first;
|
||||
while (++__first != __last)
|
||||
if (!__pred(*__result, *__first))
|
||||
*++__result = *__first;
|
||||
++__result;
|
||||
__i = __first;
|
||||
}
|
||||
}
|
||||
return __result;
|
||||
}
|
||||
return pair<_ForwardIterator, _OutputIterator>(std::move(__first), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _BinaryPredicate, class _InputIterator, class _Sent, class _InputAndOutputIterator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _InputAndOutputIterator>
|
||||
__unique_copy(_InputIterator __first,
|
||||
_Sent __last,
|
||||
_InputAndOutputIterator __result,
|
||||
_BinaryPredicate&& __pred,
|
||||
__unique_copy_tags::__reread_from_output_tag) {
|
||||
if (__first != __last) {
|
||||
*__result = *__first;
|
||||
while (++__first != __last)
|
||||
if (!__pred(*__result, *__first))
|
||||
*++__result = *__first;
|
||||
++__result;
|
||||
}
|
||||
return pair<_InputIterator, _InputAndOutputIterator>(std::move(__first), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _OutputIterator, class _BinaryPredicate>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
_OutputIterator
|
||||
unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred)
|
||||
{
|
||||
return _VSTD::__unique_copy<_BinaryPredicate&>(__first, __last, __result, __pred,
|
||||
typename iterator_traits<_InputIterator>::iterator_category(),
|
||||
typename iterator_traits<_OutputIterator>::iterator_category());
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
|
||||
unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) {
|
||||
using __algo_tag = typename conditional<
|
||||
is_base_of<forward_iterator_tag, typename iterator_traits<_InputIterator>::iterator_category>::value,
|
||||
__unique_copy_tags::__reread_from_input_tag,
|
||||
typename conditional<
|
||||
is_base_of<forward_iterator_tag, typename iterator_traits<_OutputIterator>::iterator_category>::value &&
|
||||
is_same< typename iterator_traits<_InputIterator>::value_type,
|
||||
typename iterator_traits<_OutputIterator>::value_type>::value,
|
||||
__unique_copy_tags::__reread_from_output_tag,
|
||||
__unique_copy_tags::__read_from_tmp_value_tag>::type >::type;
|
||||
return std::__unique_copy<_ClassicAlgPolicy>(
|
||||
std::move(__first), std::move(__last), std::move(__result), __pred, __algo_tag())
|
||||
.second;
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _OutputIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
_OutputIterator
|
||||
unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
|
||||
{
|
||||
typedef typename iterator_traits<_InputIterator>::value_type __v;
|
||||
return _VSTD::unique_copy(__first, __last, __result, __equal_to<__v>());
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
|
||||
unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
|
||||
typedef typename iterator_traits<_InputIterator>::value_type __v;
|
||||
return std::unique_copy(std::move(__first), std::move(__last), std::move(__result), __equal_to<__v>());
|
||||
}
|
||||
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_UNIQUE_COPY_H
|
||||
|
@ -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_UNWRAP_RANGE_H
|
||||
#define _LIBCPP___ALGORITHM_UNWRAP_RANGE_H
|
||||
|
||||
#include <__algorithm/unwrap_iter.h>
|
||||
#include <__concepts/constructible.h>
|
||||
#include <__config>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/next.h>
|
||||
#include <__utility/declval.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
|
||||
|
||||
// __unwrap_range and __rewrap_range are used to unwrap ranges which may have different iterator and sentinel types.
|
||||
// __unwrap_iter and __rewrap_iter don't work for this, because they assume that the iterator and sentinel have
|
||||
// the same type. __unwrap_range tries to get two iterators and then forward to __unwrap_iter.
|
||||
|
||||
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
template <class _Iter, class _Sent>
|
||||
struct __unwrap_range_impl {
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __sent)
|
||||
requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>
|
||||
{
|
||||
auto __last = ranges::next(__first, __sent);
|
||||
return pair{std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))};
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __last) {
|
||||
return pair{std::move(__first), std::move(__last)};
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr auto
|
||||
__rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(__orig_iter)) __iter)
|
||||
requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>
|
||||
{
|
||||
return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr auto __rewrap(const _Iter&, _Iter __iter)
|
||||
requires (!(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>))
|
||||
{
|
||||
return __iter;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Iter>
|
||||
struct __unwrap_range_impl<_Iter, _Iter> {
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Iter __last) {
|
||||
return pair{std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))};
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr auto
|
||||
__rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(__orig_iter)) __iter) {
|
||||
return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Iter, class _Sent>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto __unwrap_range(_Iter __first, _Sent __last) {
|
||||
return __unwrap_range_impl<_Iter, _Sent>::__unwrap(std::move(__first), std::move(__last));
|
||||
}
|
||||
|
||||
template <
|
||||
class _Sent,
|
||||
class _Iter,
|
||||
class _Unwrapped = decltype(std::__unwrap_range(std::declval<_Iter>(), std::declval<_Sent>()))>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) {
|
||||
return __unwrap_range_impl<_Iter, _Sent>::__rewrap(std::move(__orig_iter), std::move(__iter));
|
||||
}
|
||||
#else // _LIBCPP_STD_VER > 17
|
||||
template <class _Iter, class _Unwrapped = decltype(std::__unwrap_iter(std::declval<_Iter>()))>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair<_Unwrapped, _Unwrapped> __unwrap_range(_Iter __first, _Iter __last) {
|
||||
return std::make_pair(std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last)));
|
||||
}
|
||||
|
||||
template <class _Iter, class _Unwrapped = decltype(std::__unwrap_iter(std::declval<_Iter>()))>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) {
|
||||
return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
|
||||
}
|
||||
#endif // _LIBCPP_STD_VER > 17
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_UNWRAP_RANGE_H
|
@ -10,8 +10,8 @@
|
||||
#ifndef _LIBCPP___ASSERT
|
||||
#define _LIBCPP___ASSERT
|
||||
|
||||
#include <__availability>
|
||||
#include <__config>
|
||||
#include <__verbose_abort>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
@ -45,7 +45,7 @@
|
||||
# define _LIBCPP_ASSERT(expression, message) \
|
||||
(__builtin_expect(static_cast<bool>(expression), 1) ? \
|
||||
(void)0 : \
|
||||
::std::__libcpp_assertion_handler("%s:%d: assertion %s failed: %s", __FILE__, __LINE__, #expression, message))
|
||||
::std::__libcpp_verbose_abort("%s:%d: assertion %s failed: %s", __FILE__, __LINE__, #expression, message))
|
||||
#elif !defined(_LIBCPP_ASSERTIONS_DISABLE_ASSUME) && __has_builtin(__builtin_assume)
|
||||
# define _LIBCPP_ASSERT(expression, message) \
|
||||
(_LIBCPP_DIAGNOSTIC_PUSH \
|
||||
@ -56,11 +56,4 @@
|
||||
# define _LIBCPP_ASSERT(expression, message) ((void)0)
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_ASSERTION_HANDLER _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2)
|
||||
void __libcpp_assertion_handler(const char *__format, ...);
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ASSERT
|
||||
|
@ -156,22 +156,21 @@
|
||||
# define _LIBCPP_AVAILABILITY_FORMAT
|
||||
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
|
||||
|
||||
// This controls whether the std::__libcpp_assertion_handler default
|
||||
// assertion handler is provided by the library.
|
||||
// This controls whether the default verbose termination function is
|
||||
// provided by the library.
|
||||
//
|
||||
// Note that when users provide their own custom assertion handler,
|
||||
// it doesn't matter whether the dylib provides a default handler,
|
||||
// and the availability markup can actually give a false positive
|
||||
// diagnostic (it will think that no handler is provided, when in
|
||||
// reality the user has provided their own).
|
||||
// Note that when users provide their own custom function, it doesn't
|
||||
// matter whether the dylib provides a default function, and the
|
||||
// availability markup can actually give a false positive diagnostic
|
||||
// (it will think that no function is provided, when in reality the
|
||||
// user has provided their own).
|
||||
//
|
||||
// Users can pass -D_LIBCPP_AVAILABILITY_CUSTOM_ASSERTION_HANDLER_PROVIDED
|
||||
// to the compiler to tell the library to ignore the fact that the
|
||||
// default handler isn't available on their deployment target. Note that
|
||||
// defining this macro but failing to define a custom assertion handler
|
||||
// will lead to a load-time error on back-deployment targets, so it
|
||||
// should be avoided.
|
||||
# define _LIBCPP_AVAILABILITY_DEFAULT_ASSERTION_HANDLER
|
||||
// Users can pass -D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED
|
||||
// to the compiler to tell the library not to define its own verbose abort.
|
||||
// Note that defining this macro but failing to define a custom function
|
||||
// will lead to a load-time error on back-deployment targets, so it should
|
||||
// be avoided.
|
||||
// # define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
@ -272,8 +271,8 @@
|
||||
__attribute__((unavailable))
|
||||
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
|
||||
|
||||
# define _LIBCPP_AVAILABILITY_DEFAULT_ASSERTION_HANDLER \
|
||||
__attribute__((unavailable))
|
||||
# define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
|
||||
|
||||
#else
|
||||
|
||||
// ...New vendors can add availability markup here...
|
||||
@ -297,14 +296,4 @@
|
||||
# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
|
||||
#endif
|
||||
|
||||
// Define the special assertion handler availability attribute, which can be silenced by
|
||||
// users if they provide their own custom assertion handler. The rest of the code should
|
||||
// not use the *_DEFAULT_* macro directly, since that would make it ignore the fact that
|
||||
// the user provided a custom handler.
|
||||
#if defined(_LIBCPP_AVAILABILITY_CUSTOM_ASSERTION_HANDLER_PROVIDED)
|
||||
# define _LIBCPP_AVAILABILITY_ASSERTION_HANDLER /* nothing */
|
||||
#else
|
||||
# define _LIBCPP_AVAILABILITY_ASSERTION_HANDLER _LIBCPP_AVAILABILITY_DEFAULT_ASSERTION_HANDLER
|
||||
#endif
|
||||
|
||||
#endif // _LIBCPP___AVAILABILITY
|
||||
|
@ -10,10 +10,13 @@
|
||||
#ifndef _LIBCPP___BIT_REFERENCE
|
||||
#define _LIBCPP___BIT_REFERENCE
|
||||
|
||||
#include <__algorithm/copy_n.h>
|
||||
#include <__algorithm/fill_n.h>
|
||||
#include <__algorithm/min.h>
|
||||
#include <__bits>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__memory/construct_at.h>
|
||||
#include <__memory/pointer_traits.h>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
@ -51,15 +54,15 @@ class __bit_reference
|
||||
friend class __bit_const_reference<_Cp>;
|
||||
friend class __bit_iterator<_Cp, false>;
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__bit_reference(const __bit_reference&) = default;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 operator bool() const _NOEXCEPT
|
||||
{return static_cast<bool>(*__seg_ & __mask_);}
|
||||
_LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator ~() const _NOEXCEPT
|
||||
{return !static_cast<bool>(*this);}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__bit_reference& operator=(bool __x) _NOEXCEPT
|
||||
{
|
||||
if (__x)
|
||||
@ -70,7 +73,7 @@ public:
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER > 20
|
||||
_LIBCPP_HIDE_FROM_ABI const __bit_reference& operator=(bool __x) const noexcept {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr const __bit_reference& operator=(bool __x) const noexcept {
|
||||
if (__x)
|
||||
*__seg_ |= __mask_;
|
||||
else
|
||||
@ -79,15 +82,15 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT
|
||||
{return operator=(static_cast<bool>(__x));}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {*__seg_ ^= __mask_;}
|
||||
_LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, false> operator&() const _NOEXCEPT
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void flip() _NOEXCEPT {*__seg_ ^= __mask_;}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator<_Cp, false> operator&() const _NOEXCEPT
|
||||
{return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(__libcpp_ctz(__mask_)));}
|
||||
private:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
explicit __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
|
||||
: __seg_(__s), __mask_(__m) {}
|
||||
};
|
||||
@ -98,7 +101,7 @@ class __bit_reference<_Cp, false>
|
||||
};
|
||||
|
||||
template <class _Cp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT
|
||||
{
|
||||
@ -108,7 +111,7 @@ swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT
|
||||
}
|
||||
|
||||
template <class _Cp, class _Dp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT
|
||||
{
|
||||
@ -118,7 +121,7 @@ swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT
|
||||
}
|
||||
|
||||
template <class _Cp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT
|
||||
{
|
||||
@ -128,7 +131,7 @@ swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT
|
||||
}
|
||||
|
||||
template <class _Cp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT
|
||||
{
|
||||
@ -152,14 +155,14 @@ public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__bit_const_reference(const __bit_const_reference&) = default;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT
|
||||
: __seg_(__x.__seg_), __mask_(__x.__mask_) {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT
|
||||
{return static_cast<bool>(*__seg_ & __mask_);}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, true> operator&() const _NOEXCEPT
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator<_Cp, true> operator&() const _NOEXCEPT
|
||||
{return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(__libcpp_ctz(__mask_)));}
|
||||
private:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
@ -173,12 +176,12 @@ private:
|
||||
// find
|
||||
|
||||
template <class _Cp, bool _IsConst>
|
||||
__bit_iterator<_Cp, _IsConst>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator<_Cp, _IsConst>
|
||||
__find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
|
||||
{
|
||||
typedef __bit_iterator<_Cp, _IsConst> _It;
|
||||
typedef typename _It::__storage_type __storage_type;
|
||||
static const int __bits_per_word = _It::__bits_per_word;
|
||||
const int __bits_per_word = _It::__bits_per_word;
|
||||
// do first partial word
|
||||
if (__first.__ctz_ != 0)
|
||||
{
|
||||
@ -209,7 +212,7 @@ __find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type
|
||||
}
|
||||
|
||||
template <class _Cp, bool _IsConst>
|
||||
__bit_iterator<_Cp, _IsConst>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator<_Cp, _IsConst>
|
||||
__find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
|
||||
{
|
||||
typedef __bit_iterator<_Cp, _IsConst> _It;
|
||||
@ -248,7 +251,7 @@ __find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type
|
||||
}
|
||||
|
||||
template <class _Cp, bool _IsConst, class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__bit_iterator<_Cp, _IsConst>
|
||||
find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value)
|
||||
{
|
||||
@ -334,7 +337,7 @@ count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __las
|
||||
// fill_n
|
||||
|
||||
template <class _Cp>
|
||||
void
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 void
|
||||
__fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
|
||||
{
|
||||
typedef __bit_iterator<_Cp, false> _It;
|
||||
@ -352,7 +355,7 @@ __fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
|
||||
}
|
||||
// do middle whole words
|
||||
__storage_type __nw = __n / __bits_per_word;
|
||||
_VSTD::memset(_VSTD::__to_address(__first.__seg_), 0, __nw * sizeof(__storage_type));
|
||||
std::fill_n(std::__to_address(__first.__seg_), __nw, 0);
|
||||
__n -= __nw * __bits_per_word;
|
||||
// do last partial word
|
||||
if (__n > 0)
|
||||
@ -364,7 +367,7 @@ __fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
|
||||
}
|
||||
|
||||
template <class _Cp>
|
||||
void
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 void
|
||||
__fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
|
||||
{
|
||||
typedef __bit_iterator<_Cp, false> _It;
|
||||
@ -382,7 +385,8 @@ __fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
|
||||
}
|
||||
// do middle whole words
|
||||
__storage_type __nw = __n / __bits_per_word;
|
||||
_VSTD::memset(_VSTD::__to_address(__first.__seg_), -1, __nw * sizeof(__storage_type));
|
||||
// __storage_type is always an unsigned type, so -1 sets all bits
|
||||
std::fill_n(std::__to_address(__first.__seg_), __nw, static_cast<__storage_type>(-1));
|
||||
__n -= __nw * __bits_per_word;
|
||||
// do last partial word
|
||||
if (__n > 0)
|
||||
@ -394,7 +398,7 @@ __fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
|
||||
}
|
||||
|
||||
template <class _Cp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value)
|
||||
{
|
||||
@ -410,7 +414,7 @@ fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __v
|
||||
// fill
|
||||
|
||||
template <class _Cp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value)
|
||||
{
|
||||
@ -420,6 +424,7 @@ fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool
|
||||
// copy
|
||||
|
||||
template <class _Cp, bool _IsConst>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__bit_iterator<_Cp, false>
|
||||
__copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
|
||||
__bit_iterator<_Cp, false> __result)
|
||||
@ -449,9 +454,7 @@ __copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsCon
|
||||
// __first.__ctz_ == 0;
|
||||
// do middle words
|
||||
__storage_type __nw = __n / __bits_per_word;
|
||||
_VSTD::memmove(_VSTD::__to_address(__result.__seg_),
|
||||
_VSTD::__to_address(__first.__seg_),
|
||||
__nw * sizeof(__storage_type));
|
||||
std::copy_n(std::__to_address(__first.__seg_), __nw, std::__to_address(__result.__seg_));
|
||||
__n -= __nw * __bits_per_word;
|
||||
__result.__seg_ += __nw;
|
||||
// do last word
|
||||
@ -469,6 +472,7 @@ __copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsCon
|
||||
}
|
||||
|
||||
template <class _Cp, bool _IsConst>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__bit_iterator<_Cp, false>
|
||||
__copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
|
||||
__bit_iterator<_Cp, false> __result)
|
||||
@ -476,7 +480,7 @@ __copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsC
|
||||
typedef __bit_iterator<_Cp, _IsConst> _In;
|
||||
typedef typename _In::difference_type difference_type;
|
||||
typedef typename _In::__storage_type __storage_type;
|
||||
static const int __bits_per_word = _In::__bits_per_word;
|
||||
const int __bits_per_word = _In::__bits_per_word;
|
||||
difference_type __n = __last - __first;
|
||||
if (__n > 0)
|
||||
{
|
||||
@ -547,7 +551,7 @@ __copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsC
|
||||
}
|
||||
|
||||
template <class _Cp, bool _IsConst>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__bit_iterator<_Cp, false>
|
||||
copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
|
||||
{
|
||||
@ -559,7 +563,7 @@ copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last
|
||||
// copy_backward
|
||||
|
||||
template <class _Cp, bool _IsConst>
|
||||
__bit_iterator<_Cp, false>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator<_Cp, false>
|
||||
__copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
|
||||
__bit_iterator<_Cp, false> __result)
|
||||
{
|
||||
@ -590,9 +594,7 @@ __copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_C
|
||||
__storage_type __nw = __n / __bits_per_word;
|
||||
__result.__seg_ -= __nw;
|
||||
__last.__seg_ -= __nw;
|
||||
_VSTD::memmove(_VSTD::__to_address(__result.__seg_),
|
||||
_VSTD::__to_address(__last.__seg_),
|
||||
__nw * sizeof(__storage_type));
|
||||
std::copy_n(std::__to_address(__last.__seg_), __nw, std::__to_address(__result.__seg_));
|
||||
__n -= __nw * __bits_per_word;
|
||||
// do last word
|
||||
if (__n > 0)
|
||||
@ -608,7 +610,7 @@ __copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_C
|
||||
}
|
||||
|
||||
template <class _Cp, bool _IsConst>
|
||||
__bit_iterator<_Cp, false>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator<_Cp, false>
|
||||
__copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
|
||||
__bit_iterator<_Cp, false> __result)
|
||||
{
|
||||
@ -694,7 +696,7 @@ __copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<
|
||||
}
|
||||
|
||||
template <class _Cp, bool _IsConst>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__bit_iterator<_Cp, false>
|
||||
copy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
|
||||
{
|
||||
@ -901,14 +903,19 @@ struct __bit_array
|
||||
difference_type __size_;
|
||||
__storage_type __word_[_Np];
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY static difference_type capacity()
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 static difference_type capacity()
|
||||
{return static_cast<difference_type>(_Np * __bits_per_word);}
|
||||
_LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {}
|
||||
_LIBCPP_INLINE_VISIBILITY iterator begin()
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit __bit_array(difference_type __s) : __size_(__s) {
|
||||
if (__libcpp_is_constant_evaluated()) {
|
||||
for (size_t __i = 0; __i != __bit_array<_Cp>::_Np; ++__i)
|
||||
std::__construct_at(__word_ + __i, 0);
|
||||
}
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator begin()
|
||||
{
|
||||
return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0);
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY iterator end()
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator end()
|
||||
{
|
||||
return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word,
|
||||
static_cast<unsigned>(__size_ % __bits_per_word));
|
||||
@ -916,7 +923,7 @@ struct __bit_array
|
||||
};
|
||||
|
||||
template <class _Cp>
|
||||
__bit_iterator<_Cp, false>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator<_Cp, false>
|
||||
rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last)
|
||||
{
|
||||
typedef __bit_iterator<_Cp, false> _I1;
|
||||
@ -967,14 +974,14 @@ rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle,
|
||||
// equal
|
||||
|
||||
template <class _Cp, bool _IC1, bool _IC2>
|
||||
bool
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
|
||||
__equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
|
||||
__bit_iterator<_Cp, _IC2> __first2)
|
||||
{
|
||||
typedef __bit_iterator<_Cp, _IC1> _It;
|
||||
typedef typename _It::difference_type difference_type;
|
||||
typedef typename _It::__storage_type __storage_type;
|
||||
static const int __bits_per_word = _It::__bits_per_word;
|
||||
const int __bits_per_word = _It::__bits_per_word;
|
||||
difference_type __n = __last1 - __first1;
|
||||
if (__n > 0)
|
||||
{
|
||||
@ -1049,14 +1056,14 @@ __equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1>
|
||||
}
|
||||
|
||||
template <class _Cp, bool _IC1, bool _IC2>
|
||||
bool
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
|
||||
__equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
|
||||
__bit_iterator<_Cp, _IC2> __first2)
|
||||
{
|
||||
typedef __bit_iterator<_Cp, _IC1> _It;
|
||||
typedef typename _It::difference_type difference_type;
|
||||
typedef typename _It::__storage_type __storage_type;
|
||||
static const int __bits_per_word = _It::__bits_per_word;
|
||||
const int __bits_per_word = _It::__bits_per_word;
|
||||
difference_type __n = __last1 - __first1;
|
||||
if (__n > 0)
|
||||
{
|
||||
@ -1092,7 +1099,7 @@ __equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __
|
||||
}
|
||||
|
||||
template <class _Cp, bool _IC1, bool _IC2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
bool
|
||||
equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2)
|
||||
{
|
||||
@ -1126,7 +1133,7 @@ private:
|
||||
unsigned __ctz_;
|
||||
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator() _NOEXCEPT
|
||||
#if _LIBCPP_STD_VER > 11
|
||||
: __seg_(nullptr), __ctz_(0)
|
||||
#endif
|
||||
@ -1137,7 +1144,7 @@ public:
|
||||
// When _IsConst=true, this is a converting constructor;
|
||||
// the copy and move constructors are implicitly generated
|
||||
// and trivial.
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
|
||||
: __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
|
||||
|
||||
@ -1146,19 +1153,19 @@ public:
|
||||
// the implicit generation of a defaulted one is deprecated.
|
||||
// When _IsConst=true, the assignment operators are
|
||||
// implicitly generated and trivial.
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__bit_iterator& operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) {
|
||||
__seg_ = __it.__seg_;
|
||||
__ctz_ = __it.__ctz_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT {
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reference operator*() const _NOEXCEPT {
|
||||
return typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >
|
||||
::type(__seg_, __storage_type(1) << __ctz_);
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++()
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator& operator++()
|
||||
{
|
||||
if (__ctz_ != __bits_per_word-1)
|
||||
++__ctz_;
|
||||
@ -1170,14 +1177,14 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY __bit_iterator operator++(int)
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator operator++(int)
|
||||
{
|
||||
__bit_iterator __tmp = *this;
|
||||
++(*this);
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY __bit_iterator& operator--()
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator& operator--()
|
||||
{
|
||||
if (__ctz_ != 0)
|
||||
--__ctz_;
|
||||
@ -1189,14 +1196,14 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY __bit_iterator operator--(int)
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator operator--(int)
|
||||
{
|
||||
__bit_iterator __tmp = *this;
|
||||
--(*this);
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY __bit_iterator& operator+=(difference_type __n)
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator& operator+=(difference_type __n)
|
||||
{
|
||||
if (__n >= 0)
|
||||
__seg_ += (__n + __ctz_) / __bits_per_word;
|
||||
@ -1208,54 +1215,54 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY __bit_iterator& operator-=(difference_type __n)
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator& operator-=(difference_type __n)
|
||||
{
|
||||
return *this += -__n;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY __bit_iterator operator+(difference_type __n) const
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator operator+(difference_type __n) const
|
||||
{
|
||||
__bit_iterator __t(*this);
|
||||
__t += __n;
|
||||
return __t;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY __bit_iterator operator-(difference_type __n) const
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 __bit_iterator operator-(difference_type __n) const
|
||||
{
|
||||
__bit_iterator __t(*this);
|
||||
__t -= __n;
|
||||
return __t;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y)
|
||||
{return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const {return *(*this + __n);}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reference operator[](difference_type __n) const {return *(*this + __n);}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y)
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y)
|
||||
{return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y)
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y)
|
||||
{return !(__x == __y);}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y)
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y)
|
||||
{return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y)
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y)
|
||||
{return __y < __x;}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y)
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y)
|
||||
{return !(__y < __x);}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y)
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y)
|
||||
{return !(__x < __y);}
|
||||
|
||||
private:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
explicit __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT
|
||||
: __seg_(__s), __ctz_(__ctz) {}
|
||||
|
||||
@ -1265,26 +1272,44 @@ private:
|
||||
friend class __bit_const_reference<_Cp>;
|
||||
friend class __bit_iterator<_Cp, true>;
|
||||
template <class _Dp> friend struct __bit_array;
|
||||
template <class _Dp> friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
|
||||
template <class _Dp> friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
|
||||
template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first,
|
||||
__bit_iterator<_Dp, _IC> __last,
|
||||
__bit_iterator<_Dp, false> __result);
|
||||
template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first,
|
||||
__bit_iterator<_Dp, _IC> __last,
|
||||
__bit_iterator<_Dp, false> __result);
|
||||
template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first,
|
||||
__bit_iterator<_Dp, _IC> __last,
|
||||
__bit_iterator<_Dp, false> __result);
|
||||
template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first,
|
||||
__bit_iterator<_Dp, _IC> __last,
|
||||
__bit_iterator<_Dp, false> __result);
|
||||
template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first,
|
||||
__bit_iterator<_Dp, _IC> __last,
|
||||
__bit_iterator<_Dp, false> __result);
|
||||
template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first,
|
||||
__bit_iterator<_Dp, _IC> __last,
|
||||
__bit_iterator<_Dp, false> __result);
|
||||
template <class _Dp>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
|
||||
|
||||
template <class _Dp>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
|
||||
|
||||
template <class _Dp, bool _IC>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first,
|
||||
__bit_iterator<_Dp, _IC> __last,
|
||||
__bit_iterator<_Dp, false> __result);
|
||||
template <class _Dp, bool _IC>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first,
|
||||
__bit_iterator<_Dp, _IC> __last,
|
||||
__bit_iterator<_Dp, false> __result);
|
||||
template <class _Dp, bool _IC>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first,
|
||||
__bit_iterator<_Dp, _IC> __last,
|
||||
__bit_iterator<_Dp, false> __result);
|
||||
template <class _Dp, bool _IC>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first,
|
||||
__bit_iterator<_Dp, _IC> __last,
|
||||
__bit_iterator<_Dp, false> __result);
|
||||
template <class _Dp, bool _IC>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first,
|
||||
__bit_iterator<_Dp, _IC> __last,
|
||||
__bit_iterator<_Dp, false> __result);
|
||||
template <class _Dp, bool _IC>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first,
|
||||
__bit_iterator<_Dp, _IC> __last,
|
||||
__bit_iterator<_Dp, false> __result);
|
||||
template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>,
|
||||
__bit_iterator<__C1, false>,
|
||||
__bit_iterator<__C2, false>);
|
||||
@ -1294,22 +1319,32 @@ private:
|
||||
template <class __C1, class __C2>friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>,
|
||||
__bit_iterator<__C1, false>,
|
||||
__bit_iterator<__C2, false>);
|
||||
template <class _Dp> friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>,
|
||||
__bit_iterator<_Dp, false>,
|
||||
__bit_iterator<_Dp, false>);
|
||||
template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>,
|
||||
__bit_iterator<_Dp, _IC1>,
|
||||
__bit_iterator<_Dp, _IC2>);
|
||||
template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>,
|
||||
__bit_iterator<_Dp, _IC1>,
|
||||
__bit_iterator<_Dp, _IC2>);
|
||||
template <class _Dp, bool _IC1, bool _IC2> friend bool equal(__bit_iterator<_Dp, _IC1>,
|
||||
__bit_iterator<_Dp, _IC1>,
|
||||
__bit_iterator<_Dp, _IC2>);
|
||||
template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>,
|
||||
typename _Dp::size_type);
|
||||
template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>,
|
||||
typename _Dp::size_type);
|
||||
template <class _Dp>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>,
|
||||
__bit_iterator<_Dp, false>,
|
||||
__bit_iterator<_Dp, false>);
|
||||
template <class _Dp, bool _IC1, bool _IC2>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>,
|
||||
__bit_iterator<_Dp, _IC1>,
|
||||
__bit_iterator<_Dp, _IC2>);
|
||||
template <class _Dp, bool _IC1, bool _IC2>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>,
|
||||
__bit_iterator<_Dp, _IC1>,
|
||||
__bit_iterator<_Dp, _IC2>);
|
||||
template <class _Dp, bool _IC1, bool _IC2>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend bool equal(__bit_iterator<_Dp, _IC1>,
|
||||
__bit_iterator<_Dp, _IC1>,
|
||||
__bit_iterator<_Dp, _IC2>);
|
||||
template <class _Dp, bool _IC>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
|
||||
template <class _Dp, bool _IC>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
|
||||
template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
|
||||
__count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
|
||||
template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <__config>
|
||||
#include <__type_traits/is_primary_template.h>
|
||||
#include <concepts>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <__iterator/incrementable_traits.h>
|
||||
#include <__iterator/readable_traits.h>
|
||||
#include <concepts>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
@ -507,6 +508,12 @@ using __iterator_category_type = typename iterator_traits<_Iter>::iterator_categ
|
||||
template <class _Iter>
|
||||
using __iterator_pointer_type = typename iterator_traits<_Iter>::pointer;
|
||||
|
||||
template <class _Iter>
|
||||
using __iter_diff_t = typename iterator_traits<_Iter>::difference_type;
|
||||
|
||||
template<class _InputIterator>
|
||||
using __iter_value_type = typename iterator_traits<_InputIterator>::value_type;
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ITERATOR_ITERATOR_TRAITS_H
|
||||
|
@ -70,9 +70,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
|
||||
typename iterator_traits<_Iter>::iterator_category>;
|
||||
using pointer = typename iterator_traits<_Iter>::pointer;
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
using iterator_concept = _If<__is_cpp17_random_access_iterator<_Iter>::value,
|
||||
random_access_iterator_tag,
|
||||
bidirectional_iterator_tag>;
|
||||
using iterator_concept = _If<random_access_iterator<_Iter>, random_access_iterator_tag, bidirectional_iterator_tag>;
|
||||
using value_type = iter_value_t<_Iter>;
|
||||
using difference_type = iter_difference_t<_Iter>;
|
||||
using reference = iter_reference_t<_Iter>;
|
||||
@ -365,7 +363,7 @@ class __unconstrained_reverse_iterator {
|
||||
_Iter __iter_;
|
||||
|
||||
public:
|
||||
static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value);
|
||||
static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>);
|
||||
|
||||
using iterator_type = _Iter;
|
||||
using iterator_category =
|
||||
@ -393,6 +391,14 @@ class __unconstrained_reverse_iterator {
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr
|
||||
iter_rvalue_reference_t<_Iter> iter_move(const __unconstrained_reverse_iterator& __i)
|
||||
noexcept(is_nothrow_copy_constructible_v<_Iter> &&
|
||||
noexcept(ranges::iter_move(--declval<_Iter&>()))) {
|
||||
auto __tmp = __i.base();
|
||||
return ranges::iter_move(--__tmp);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator++() {
|
||||
--__iter_;
|
||||
return *this;
|
||||
|
@ -42,7 +42,8 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* __construct_at(_Tp* __location, _Ar
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
return std::construct_at(__location, std::forward<_Args>(__args)...);
|
||||
#else
|
||||
return ::new (std::__voidify(*__location)) _Tp(std::forward<_Args>(__args)...);
|
||||
return _LIBCPP_ASSERT(__location != nullptr, "null pointer given to construct_at"),
|
||||
::new (std::__voidify(*__location)) _Tp(std::forward<_Args>(__args)...);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <__config>
|
||||
#include <__memory/addressof.h>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
@ -122,7 +123,7 @@ struct _LIBCPP_TEMPLATE_VIS pointer_traits
|
||||
private:
|
||||
struct __nat {};
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
static pointer pointer_to(typename conditional<is_void<element_type>::value,
|
||||
__nat, element_type>::type& __r)
|
||||
{return pointer::pointer_to(__r);}
|
||||
@ -171,9 +172,30 @@ _Tp* __to_address(_Tp* __p) _NOEXCEPT {
|
||||
return __p;
|
||||
}
|
||||
|
||||
template <class _Pointer, class = void>
|
||||
struct _HasToAddress : false_type {};
|
||||
|
||||
template <class _Pointer>
|
||||
struct _HasToAddress<_Pointer,
|
||||
decltype((void)pointer_traits<_Pointer>::to_address(declval<const _Pointer&>()))
|
||||
> : true_type {};
|
||||
|
||||
template <class _Pointer, class = void>
|
||||
struct _HasArrow : false_type {};
|
||||
|
||||
template <class _Pointer>
|
||||
struct _HasArrow<_Pointer,
|
||||
decltype((void)declval<const _Pointer&>().operator->())
|
||||
> : true_type {};
|
||||
|
||||
template <class _Pointer>
|
||||
struct _IsFancyPointer {
|
||||
static const bool value = _HasArrow<_Pointer>::value || _HasToAddress<_Pointer>::value;
|
||||
};
|
||||
|
||||
// enable_if is needed here to avoid instantiating checks for fancy pointers on raw pointers
|
||||
template <class _Pointer, class = __enable_if_t<
|
||||
!is_pointer<_Pointer>::value && !is_array<_Pointer>::value && !is_function<_Pointer>::value
|
||||
_And<is_class<_Pointer>, _IsFancyPointer<_Pointer> >::value
|
||||
> >
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
|
||||
typename decay<decltype(__to_address_helper<_Pointer>::__call(declval<const _Pointer&>()))>::type
|
||||
@ -208,7 +230,7 @@ auto to_address(_Tp *__p) noexcept {
|
||||
|
||||
template <class _Pointer>
|
||||
inline _LIBCPP_INLINE_VISIBILITY constexpr
|
||||
auto to_address(const _Pointer& __p) noexcept {
|
||||
auto to_address(const _Pointer& __p) noexcept -> decltype(std::__to_address(__p)) {
|
||||
return _VSTD::__to_address(__p);
|
||||
}
|
||||
#endif
|
||||
|
@ -509,10 +509,11 @@ __allocator_destroy(_Alloc& __alloc, _Iter __first, _Sent __last) {
|
||||
template <class _Alloc, class _Iter>
|
||||
class _AllocatorDestroyRangeReverse {
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI _AllocatorDestroyRangeReverse(_Alloc& __alloc, _Iter& __first, _Iter& __last)
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
_AllocatorDestroyRangeReverse(_Alloc& __alloc, _Iter& __first, _Iter& __last)
|
||||
: __alloc_(__alloc), __first_(__first), __last_(__last) {}
|
||||
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX11 void operator()() const {
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 void operator()() const {
|
||||
std::__allocator_destroy(__alloc_, std::reverse_iterator<_Iter>(__last_), std::reverse_iterator<_Iter>(__first_));
|
||||
}
|
||||
|
||||
@ -621,7 +622,7 @@ template <
|
||||
class _Type = typename iterator_traits<_Iter1>::value_type,
|
||||
class = __enable_if_t<is_trivially_move_constructible<_Type>::value && is_trivially_move_assignable<_Type>::value &&
|
||||
__allocator_has_trivial_move_construct<_Alloc, _Type>::value> >
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _Iter1
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _Iter2
|
||||
__uninitialized_allocator_move_if_noexcept(_Alloc&, _Iter1 __first1, _Iter1 __last1, _Iter2 __first2) {
|
||||
if (__libcpp_is_constant_evaluated()) {
|
||||
while (__first1 != __last1) {
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <__ranges/access.h>
|
||||
#include <__utility/auto_cast.h>
|
||||
#include <concepts>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
|
@ -62,107 +62,107 @@ public:
|
||||
typedef typename add_lvalue_reference<allocator_type>::type __alloc_ref;
|
||||
typedef typename add_lvalue_reference<allocator_type>::type __alloc_const_ref;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY __alloc_rr& __alloc() _NOEXCEPT {return __end_cap_.second();}
|
||||
_LIBCPP_INLINE_VISIBILITY const __alloc_rr& __alloc() const _NOEXCEPT {return __end_cap_.second();}
|
||||
_LIBCPP_INLINE_VISIBILITY pointer& __end_cap() _NOEXCEPT {return __end_cap_.first();}
|
||||
_LIBCPP_INLINE_VISIBILITY const pointer& __end_cap() const _NOEXCEPT {return __end_cap_.first();}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY __alloc_rr& __alloc() _NOEXCEPT {return __end_cap_.second();}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY const __alloc_rr& __alloc() const _NOEXCEPT {return __end_cap_.second();}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY pointer& __end_cap() _NOEXCEPT {return __end_cap_.first();}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY const pointer& __end_cap() const _NOEXCEPT {return __end_cap_.first();}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
||||
__split_buffer()
|
||||
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
||||
explicit __split_buffer(__alloc_rr& __a);
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
||||
explicit __split_buffer(const __alloc_rr& __a);
|
||||
__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a);
|
||||
~__split_buffer();
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a);
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 ~__split_buffer();
|
||||
|
||||
__split_buffer(__split_buffer&& __c)
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 __split_buffer(__split_buffer&& __c)
|
||||
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
|
||||
__split_buffer(__split_buffer&& __c, const __alloc_rr& __a);
|
||||
__split_buffer& operator=(__split_buffer&& __c)
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 __split_buffer(__split_buffer&& __c, const __alloc_rr& __a);
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 __split_buffer& operator=(__split_buffer&& __c)
|
||||
_NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
|
||||
is_nothrow_move_assignable<allocator_type>::value) ||
|
||||
!__alloc_traits::propagate_on_container_move_assignment::value);
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY iterator begin() _NOEXCEPT {return __begin_;}
|
||||
_LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return __begin_;}
|
||||
_LIBCPP_INLINE_VISIBILITY iterator end() _NOEXCEPT {return __end_;}
|
||||
_LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT {return __end_;}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY iterator begin() _NOEXCEPT {return __begin_;}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return __begin_;}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY iterator end() _NOEXCEPT {return __end_;}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT {return __end_;}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
||||
void clear() _NOEXCEPT
|
||||
{__destruct_at_end(__begin_);}
|
||||
_LIBCPP_INLINE_VISIBILITY size_type size() const {return static_cast<size_type>(__end_ - __begin_);}
|
||||
_LIBCPP_INLINE_VISIBILITY bool empty() const {return __end_ == __begin_;}
|
||||
_LIBCPP_INLINE_VISIBILITY size_type capacity() const {return static_cast<size_type>(__end_cap() - __first_);}
|
||||
_LIBCPP_INLINE_VISIBILITY size_type __front_spare() const {return static_cast<size_type>(__begin_ - __first_);}
|
||||
_LIBCPP_INLINE_VISIBILITY size_type __back_spare() const {return static_cast<size_type>(__end_cap() - __end_);}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY size_type size() const {return static_cast<size_type>(__end_ - __begin_);}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool empty() const {return __end_ == __begin_;}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY size_type capacity() const {return static_cast<size_type>(__end_cap() - __first_);}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY size_type __front_spare() const {return static_cast<size_type>(__begin_ - __first_);}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY size_type __back_spare() const {return static_cast<size_type>(__end_cap() - __end_);}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY reference front() {return *__begin_;}
|
||||
_LIBCPP_INLINE_VISIBILITY const_reference front() const {return *__begin_;}
|
||||
_LIBCPP_INLINE_VISIBILITY reference back() {return *(__end_ - 1);}
|
||||
_LIBCPP_INLINE_VISIBILITY const_reference back() const {return *(__end_ - 1);}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY reference front() {return *__begin_;}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY const_reference front() const {return *__begin_;}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY reference back() {return *(__end_ - 1);}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY const_reference back() const {return *(__end_ - 1);}
|
||||
|
||||
void reserve(size_type __n);
|
||||
void shrink_to_fit() _NOEXCEPT;
|
||||
void push_front(const_reference __x);
|
||||
_LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
|
||||
void push_front(value_type&& __x);
|
||||
void push_back(value_type&& __x);
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 void reserve(size_type __n);
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 void shrink_to_fit() _NOEXCEPT;
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 void push_front(const_reference __x);
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 void push_front(value_type&& __x);
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 void push_back(value_type&& __x);
|
||||
template <class... _Args>
|
||||
void emplace_back(_Args&&... __args);
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 void emplace_back(_Args&&... __args);
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY void pop_front() {__destruct_at_begin(__begin_+1);}
|
||||
_LIBCPP_INLINE_VISIBILITY void pop_back() {__destruct_at_end(__end_-1);}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY void pop_front() {__destruct_at_begin(__begin_+1);}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY void pop_back() {__destruct_at_end(__end_-1);}
|
||||
|
||||
void __construct_at_end(size_type __n);
|
||||
void __construct_at_end(size_type __n, const_reference __x);
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct_at_end(size_type __n);
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct_at_end(size_type __n, const_reference __x);
|
||||
template <class _InputIter>
|
||||
__enable_if_t<__is_exactly_cpp17_input_iterator<_InputIter>::value>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIter>::value>
|
||||
__construct_at_end(_InputIter __first, _InputIter __last);
|
||||
template <class _ForwardIterator>
|
||||
__enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value>
|
||||
__construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY void __destruct_at_begin(pointer __new_begin)
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY void __destruct_at_begin(pointer __new_begin)
|
||||
{__destruct_at_begin(__new_begin, is_trivially_destructible<value_type>());}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
||||
void __destruct_at_begin(pointer __new_begin, false_type);
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
||||
void __destruct_at_begin(pointer __new_begin, true_type);
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
||||
void __destruct_at_end(pointer __new_last) _NOEXCEPT
|
||||
{__destruct_at_end(__new_last, false_type());}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
||||
void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT;
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
||||
void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT;
|
||||
|
||||
void swap(__split_buffer& __x)
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(__split_buffer& __x)
|
||||
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
|
||||
__is_nothrow_swappable<__alloc_rr>::value);
|
||||
|
||||
bool __invariants() const;
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 bool __invariants() const;
|
||||
|
||||
private:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
||||
void __move_assign_alloc(__split_buffer& __c, true_type)
|
||||
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
|
||||
{
|
||||
__alloc() = _VSTD::move(__c.__alloc());
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
||||
void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT
|
||||
{}
|
||||
|
||||
struct _ConstructTransaction {
|
||||
explicit _ConstructTransaction(pointer* __p, size_type __n) _NOEXCEPT
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 explicit _ConstructTransaction(pointer* __p, size_type __n) _NOEXCEPT
|
||||
: __pos_(*__p), __end_(*__p + __n), __dest_(__p) {
|
||||
}
|
||||
~_ConstructTransaction() {
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 ~_ConstructTransaction() {
|
||||
*__dest_ = __pos_;
|
||||
}
|
||||
pointer __pos_;
|
||||
@ -173,6 +173,7 @@ private:
|
||||
};
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
bool
|
||||
__split_buffer<_Tp, _Allocator>::__invariants() const
|
||||
{
|
||||
@ -203,6 +204,7 @@ __split_buffer<_Tp, _Allocator>::__invariants() const
|
||||
// Precondition: size() + __n <= capacity()
|
||||
// Postcondition: size() == size() + __n
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n)
|
||||
{
|
||||
@ -219,6 +221,7 @@ __split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n)
|
||||
// Postcondition: size() == old size() + __n
|
||||
// Postcondition: [i] == __x for all i in [size() - __n, __n)
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
|
||||
{
|
||||
@ -231,7 +234,7 @@ __split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_referen
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
template <class _InputIter>
|
||||
__enable_if_t<__is_exactly_cpp17_input_iterator<_InputIter>::value>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIter>::value>
|
||||
__split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last)
|
||||
{
|
||||
__alloc_rr& __a = this->__alloc();
|
||||
@ -254,7 +257,7 @@ __split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIt
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
template <class _ForwardIterator>
|
||||
__enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value>
|
||||
__split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)
|
||||
{
|
||||
_ConstructTransaction __tx(&this->__end_, _VSTD::distance(__first, __last));
|
||||
@ -265,6 +268,7 @@ __split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _F
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
inline
|
||||
void
|
||||
__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type)
|
||||
@ -274,6 +278,7 @@ __split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
inline
|
||||
void
|
||||
__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type)
|
||||
@ -282,6 +287,7 @@ __split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_t
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT
|
||||
@ -291,6 +297,7 @@ __split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_typ
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, true_type) _NOEXCEPT
|
||||
@ -299,6 +306,7 @@ __split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, true_type
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a)
|
||||
: __end_cap_(nullptr, __a)
|
||||
{
|
||||
@ -314,6 +322,7 @@ __split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __sta
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
inline
|
||||
__split_buffer<_Tp, _Allocator>::__split_buffer()
|
||||
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
|
||||
@ -322,6 +331,7 @@ __split_buffer<_Tp, _Allocator>::__split_buffer()
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
inline
|
||||
__split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a)
|
||||
: __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
|
||||
@ -329,6 +339,7 @@ __split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a)
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
inline
|
||||
__split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a)
|
||||
: __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
|
||||
@ -336,6 +347,7 @@ __split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a)
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__split_buffer<_Tp, _Allocator>::~__split_buffer()
|
||||
{
|
||||
clear();
|
||||
@ -344,6 +356,7 @@ __split_buffer<_Tp, _Allocator>::~__split_buffer()
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c)
|
||||
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
|
||||
: __first_(_VSTD::move(__c.__first_)),
|
||||
@ -358,6 +371,7 @@ __split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c)
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a)
|
||||
: __end_cap_(nullptr, __a)
|
||||
{
|
||||
@ -384,6 +398,7 @@ __split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __al
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
__split_buffer<_Tp, _Allocator>&
|
||||
__split_buffer<_Tp, _Allocator>::operator=(__split_buffer&& __c)
|
||||
_NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
|
||||
@ -404,6 +419,7 @@ __split_buffer<_Tp, _Allocator>::operator=(__split_buffer&& __c)
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
__split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x)
|
||||
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
|
||||
@ -417,6 +433,7 @@ __split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x)
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
__split_buffer<_Tp, _Allocator>::reserve(size_type __n)
|
||||
{
|
||||
@ -433,6 +450,7 @@ __split_buffer<_Tp, _Allocator>::reserve(size_type __n)
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
__split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
|
||||
{
|
||||
@ -460,6 +478,7 @@ __split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
__split_buffer<_Tp, _Allocator>::push_front(const_reference __x)
|
||||
{
|
||||
@ -489,6 +508,7 @@ __split_buffer<_Tp, _Allocator>::push_front(const_reference __x)
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
__split_buffer<_Tp, _Allocator>::push_front(value_type&& __x)
|
||||
{
|
||||
@ -519,6 +539,7 @@ __split_buffer<_Tp, _Allocator>::push_front(value_type&& __x)
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
__split_buffer<_Tp, _Allocator>::push_back(const_reference __x)
|
||||
@ -549,6 +570,7 @@ __split_buffer<_Tp, _Allocator>::push_back(const_reference __x)
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
__split_buffer<_Tp, _Allocator>::push_back(value_type&& __x)
|
||||
{
|
||||
@ -580,6 +602,7 @@ __split_buffer<_Tp, _Allocator>::push_back(value_type&& __x)
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
template <class... _Args>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
void
|
||||
__split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args)
|
||||
{
|
||||
@ -610,6 +633,7 @@ __split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args)
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
swap(__split_buffer<_Tp, _Allocator>& __x, __split_buffer<_Tp, _Allocator>& __y)
|
||||
|
51
contrib/llvm-project/libcxx/include/__verbose_abort
Normal file
51
contrib/llvm-project/libcxx/include/__verbose_abort
Normal file
@ -0,0 +1,51 @@
|
||||
// -*- 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___VERBOSE_ABORT
|
||||
#define _LIBCPP___VERBOSE_ABORT
|
||||
|
||||
#include <__availability>
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
// Provide a default implementation of __libcpp_verbose_abort if we know that neither the built
|
||||
// library not the user is providing one. Otherwise, just declare it and use the one from the
|
||||
// built library or the one provided by the user.
|
||||
//
|
||||
// We can't provide a great implementation because it needs to be pretty much
|
||||
// dependency-free (this is included everywhere else in the library).
|
||||
#if defined(_LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY) && !defined(_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED)
|
||||
|
||||
extern "C" void abort();
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_NORETURN _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) _LIBCPP_HIDE_FROM_ABI inline
|
||||
void __libcpp_verbose_abort(const char *, ...) {
|
||||
::abort();
|
||||
__builtin_unreachable(); // never reached, but needed to tell the compiler that the function never returns
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#else
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_NORETURN _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2)
|
||||
void __libcpp_verbose_abort(const char *__format, ...);
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _LIBCPP___VERBOSE_ABORT
|
@ -446,6 +446,25 @@ namespace ranges {
|
||||
indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
|
||||
constexpr bool ranges::none_of(R&& r, Pred pred, Proj proj = {}); // since C++20
|
||||
|
||||
template<input_iterator I1, sentinel_for<I1> S1,
|
||||
random_access_iterator I2, sentinel_for<I2> S2,
|
||||
class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity>
|
||||
requires indirectly_copyable<I1, I2> && sortable<I2, Comp, Proj2> &&
|
||||
indirect_strict_weak_order<Comp, projected<I1, Proj1>, projected<I2, Proj2>>
|
||||
constexpr partial_sort_copy_result<I1, I2>
|
||||
partial_sort_copy(I1 first, S1 last, I2 result_first, S2 result_last,
|
||||
Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20
|
||||
|
||||
template<input_range R1, random_access_range R2, class Comp = ranges::less,
|
||||
class Proj1 = identity, class Proj2 = identity>
|
||||
requires indirectly_copyable<iterator_t<R1>, iterator_t<R2>> &&
|
||||
sortable<iterator_t<R2>, Comp, Proj2> &&
|
||||
indirect_strict_weak_order<Comp, projected<iterator_t<R1>, Proj1>,
|
||||
projected<iterator_t<R2>, Proj2>>
|
||||
constexpr partial_sort_copy_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>>
|
||||
partial_sort_copy(R1&& r, R2&& result_r, Comp comp = {},
|
||||
Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20
|
||||
|
||||
template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
|
||||
indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
|
||||
constexpr bool ranges::is_sorted(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
|
||||
@ -574,6 +593,11 @@ namespace ranges {
|
||||
constexpr borrowed_iterator_t<R>
|
||||
ranges::replace_if(R&& r, Pred pred, const T& new_value, Proj proj = {}); // since C++20
|
||||
|
||||
template<class T, class Proj = identity,
|
||||
indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
|
||||
constexpr const T&
|
||||
ranges::clamp(const T& v, const T& lo, const T& hi, Comp comp = {}, Proj proj = {}); // since C++20
|
||||
|
||||
template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
|
||||
class Proj1 = identity, class Proj2 = identity,
|
||||
indirect_strict_weak_order<projected<I1, Proj1>,
|
||||
@ -726,6 +750,13 @@ namespace ranges {
|
||||
constexpr ranges::reverse_copy_result<borrowed_iterator_t<R>, O>
|
||||
ranges::reverse_copy(R&& r, O result); // since C++20
|
||||
|
||||
template<permutable I, sentinel_for<I> S>
|
||||
constexpr subrange<I> rotate(I first, I middle, S last); // since C++20
|
||||
|
||||
template<forward_range R>
|
||||
requires permutable<iterator_t<R>>
|
||||
constexpr borrowed_subrange_t<R> rotate(R&& r, iterator_t<R> middle); // Since C++20
|
||||
|
||||
template <class _InIter, class _OutIter>
|
||||
using rotate_copy_result = in_out_result<_InIter, _OutIter>; // since C++20
|
||||
|
||||
@ -739,6 +770,18 @@ namespace ranges {
|
||||
constexpr ranges::rotate_copy_result<borrowed_iterator_t<R>, O>
|
||||
ranges::rotate_copy(R&& r, iterator_t<R> middle, O result); // since C++20
|
||||
|
||||
template<input_iterator I, sentinel_for<I> S, weakly_incrementable O, class Gen>
|
||||
requires (forward_iterator<I> || random_access_iterator<O>) &&
|
||||
indirectly_copyable<I, O> &&
|
||||
uniform_random_bit_generator<remove_reference_t<Gen>>
|
||||
O sample(I first, S last, O out, iter_difference_t<I> n, Gen&& g); // Since C++20
|
||||
|
||||
template<input_range R, weakly_incrementable O, class Gen>
|
||||
requires (forward_range<R> || random_access_iterator<O>) &&
|
||||
indirectly_copyable<iterator_t<R>, O> &&
|
||||
uniform_random_bit_generator<remove_reference_t<Gen>>
|
||||
O sample(R&& r, O out, range_difference_t<R> n, Gen&& g); // Since C++20
|
||||
|
||||
template<random_access_iterator I, sentinel_for<I> S, class Gen>
|
||||
requires permutable<I> &&
|
||||
uniform_random_bit_generator<remove_reference_t<Gen>>
|
||||
@ -749,6 +792,21 @@ namespace ranges {
|
||||
uniform_random_bit_generator<remove_reference_t<Gen>>
|
||||
borrowed_iterator_t<R> shuffle(R&& r, Gen&& g); // Since C++20
|
||||
|
||||
template<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2,
|
||||
sentinel_for<I2> S2, class Proj1 = identity, class Proj2 = identity,
|
||||
indirect_equivalence_relation<projected<I1, Proj1>,
|
||||
projected<I2, Proj2>> Pred = ranges::equal_to>
|
||||
constexpr bool ranges::is_permutation(I1 first1, S1 last1, I2 first2, S2 last2,
|
||||
Pred pred = {},
|
||||
Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20
|
||||
|
||||
template<forward_range R1, forward_range R2,
|
||||
class Proj1 = identity, class Proj2 = identity,
|
||||
indirect_equivalence_relation<projected<iterator_t<R1>, Proj1>,
|
||||
projected<iterator_t<R2>, Proj2>> Pred = ranges::equal_to>
|
||||
constexpr bool ranges::is_permutation(R1&& r1, R2&& r2, Pred pred = {},
|
||||
Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20
|
||||
|
||||
template<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2,
|
||||
sentinel_for<I2> S2, class Pred = ranges::equal_to,
|
||||
class Proj1 = identity, class Proj2 = identity>
|
||||
@ -803,7 +861,7 @@ namespace ranges {
|
||||
set_symmetric_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result,
|
||||
Comp comp = {}, Proj1 proj1 = {},
|
||||
Proj2 proj2 = {}); // since C++20
|
||||
|
||||
|
||||
template<input_range R1, input_range R2, weakly_incrementable O,
|
||||
class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity>
|
||||
requires mergeable<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2>
|
||||
@ -816,13 +874,13 @@ namespace ranges {
|
||||
indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less>
|
||||
constexpr subrange<I>
|
||||
equal_range(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); // since C++20
|
||||
|
||||
|
||||
template<forward_range R, class T, class Proj = identity,
|
||||
indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Comp =
|
||||
ranges::less>
|
||||
constexpr borrowed_subrange_t<R>
|
||||
equal_range(R&& r, const T& value, Comp comp = {}, Proj proj = {}); // since C++20
|
||||
|
||||
|
||||
template<class I1, class I2, class O>
|
||||
using set_union_result = in_in_out_result<I1, I2, O>; // since C++20
|
||||
|
||||
@ -847,15 +905,154 @@ namespace ranges {
|
||||
ranges::less>
|
||||
constexpr bool includes(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {},
|
||||
Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20
|
||||
|
||||
|
||||
template<input_range R1, input_range R2, class Proj1 = identity,
|
||||
class Proj2 = identity,
|
||||
indirect_strict_weak_order<projected<iterator_t<R1>, Proj1>,
|
||||
projected<iterator_t<R2>, Proj2>> Comp = ranges::less>
|
||||
constexpr bool includes(R1&& r1, R2&& r2, Comp comp = {},
|
||||
Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20
|
||||
|
||||
template<bidirectional_iterator I, sentinel_for<I> S, class Comp = ranges::less,
|
||||
class Proj = identity>
|
||||
requires sortable<I, Comp, Proj>
|
||||
I inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {}); // Since C++20
|
||||
|
||||
template<bidirectional_range R, class Comp = ranges::less, class Proj = identity>
|
||||
requires sortable<iterator_t<R>, Comp, Proj>
|
||||
borrowed_iterator_t<R>
|
||||
inplace_merge(R&& r, iterator_t<R> middle, Comp comp = {},
|
||||
Proj proj = {}); // Since C++20
|
||||
|
||||
template<permutable I, sentinel_for<I> S, class Proj = identity,
|
||||
indirect_equivalence_relation<projected<I, Proj>> C = ranges::equal_to>
|
||||
constexpr subrange<I> unique(I first, S last, C comp = {}, Proj proj = {}); // Since C++20
|
||||
|
||||
template<forward_range R, class Proj = identity,
|
||||
indirect_equivalence_relation<projected<iterator_t<R>, Proj>> C = ranges::equal_to>
|
||||
requires permutable<iterator_t<R>>
|
||||
constexpr borrowed_subrange_t<R>
|
||||
unique(R&& r, C comp = {}, Proj proj = {}); // Since C++20
|
||||
|
||||
template<input_iterator I, sentinel_for<I> S, weakly_incrementable O, class Proj = identity,
|
||||
indirect_equivalence_relation<projected<I, Proj>> C = ranges::equal_to>
|
||||
requires indirectly_copyable<I, O> &&
|
||||
(forward_iterator<I> ||
|
||||
(input_iterator<O> && same_as<iter_value_t<I>, iter_value_t<O>>) ||
|
||||
indirectly_copyable_storable<I, O>)
|
||||
constexpr unique_copy_result<I, O>
|
||||
unique_copy(I first, S last, O result, C comp = {}, Proj proj = {}); // Since C++20
|
||||
|
||||
template<input_range R, weakly_incrementable O, class Proj = identity,
|
||||
indirect_equivalence_relation<projected<iterator_t<R>, Proj>> C = ranges::equal_to>
|
||||
requires indirectly_copyable<iterator_t<R>, O> &&
|
||||
(forward_iterator<iterator_t<R>> ||
|
||||
(input_iterator<O> && same_as<range_value_t<R>, iter_value_t<O>>) ||
|
||||
indirectly_copyable_storable<iterator_t<R>, O>)
|
||||
constexpr unique_copy_result<borrowed_iterator_t<R>, O>
|
||||
unique_copy(R&& r, O result, C comp = {}, Proj proj = {}); // Since C++20
|
||||
|
||||
template<class I, class O>
|
||||
using remove_copy_result = in_out_result<I, O>; // Since C++20
|
||||
|
||||
template<input_iterator I, sentinel_for<I> S, weakly_incrementable O, class T,
|
||||
class Proj = identity>
|
||||
indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>
|
||||
constexpr remove_copy_result<I, O>
|
||||
remove_copy(I first, S last, O result, const T& value, Proj proj = {}); // Since C++20
|
||||
|
||||
template<input_range R, weakly_incrementable O, class T, class Proj = identity>
|
||||
requires indirectly_copyable<iterator_t<R>, O> &&
|
||||
indirect_binary_predicate<ranges::equal_to,
|
||||
projected<iterator_t<R>, Proj>, const T*>
|
||||
constexpr remove_copy_result<borrowed_iterator_t<R>, O>
|
||||
remove_copy(R&& r, O result, const T& value, Proj proj = {}); // Since C++20
|
||||
|
||||
template<class I, class O>
|
||||
using remove_copy_if_result = in_out_result<I, O>; // Since C++20
|
||||
|
||||
template<input_iterator I, sentinel_for<I> S, weakly_incrementable O,
|
||||
class Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred>
|
||||
requires indirectly_copyable<I, O>
|
||||
constexpr remove_copy_if_result<I, O>
|
||||
remove_copy_if(I first, S last, O result, Pred pred, Proj proj = {}); // Since C++20
|
||||
|
||||
template<input_range R, weakly_incrementable O, class Proj = identity,
|
||||
indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
|
||||
requires indirectly_copyable<iterator_t<R>, O>
|
||||
constexpr remove_copy_if_result<borrowed_iterator_t<R>, O>
|
||||
remove_copy_if(R&& r, O result, Pred pred, Proj proj = {}); // Since C++20
|
||||
|
||||
template<class I, class O>
|
||||
using replace_copy_result = in_out_result<I, O>; // Since C++20
|
||||
|
||||
template<input_iterator I, sentinel_for<I> S, class T1, class T2,
|
||||
output_iterator<const T2&> O, class Proj = identity>
|
||||
requires indirectly_copyable<I, O> &&
|
||||
indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T1*>
|
||||
constexpr replace_copy_result<I, O>
|
||||
replace_copy(I first, S last, O result, const T1& old_value, const T2& new_value,
|
||||
Proj proj = {}); // Since C++20
|
||||
|
||||
template<input_range R, class T1, class T2, output_iterator<const T2&> O,
|
||||
class Proj = identity>
|
||||
requires indirectly_copyable<iterator_t<R>, O> &&
|
||||
indirect_binary_predicate<ranges::equal_to,
|
||||
projected<iterator_t<R>, Proj>, const T1*>
|
||||
constexpr replace_copy_result<borrowed_iterator_t<R>, O>
|
||||
replace_copy(R&& r, O result, const T1& old_value, const T2& new_value,
|
||||
Proj proj = {}); // Since C++20
|
||||
|
||||
template<class I, class O>
|
||||
using replace_copy_if_result = in_out_result<I, O>; // Since C++20
|
||||
|
||||
template<input_iterator I, sentinel_for<I> S, class T, output_iterator<const T&> O,
|
||||
class Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred>
|
||||
requires indirectly_copyable<I, O>
|
||||
constexpr replace_copy_if_result<I, O>
|
||||
replace_copy_if(I first, S last, O result, Pred pred, const T& new_value,
|
||||
Proj proj = {}); // Since C++20
|
||||
|
||||
template<input_range R, class T, output_iterator<const T&> O, class Proj = identity,
|
||||
indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
|
||||
requires indirectly_copyable<iterator_t<R>, O>
|
||||
constexpr replace_copy_if_result<borrowed_iterator_t<R>, O>
|
||||
replace_copy_if(R&& r, O result, Pred pred, const T& new_value,
|
||||
Proj proj = {}); // Since C++20
|
||||
|
||||
template<class I>
|
||||
using prev_permutation_result = in_found_result<I>; // Since C++20
|
||||
|
||||
template<bidirectional_iterator I, sentinel_for<I> S, class Comp = ranges::less,
|
||||
class Proj = identity>
|
||||
requires sortable<I, Comp, Proj>
|
||||
constexpr ranges::prev_permutation_result<I>
|
||||
ranges::prev_permutation(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20
|
||||
|
||||
template<bidirectional_range R, class Comp = ranges::less,
|
||||
class Proj = identity>
|
||||
requires sortable<iterator_t<R>, Comp, Proj>
|
||||
constexpr ranges::prev_permutation_result<borrowed_iterator_t<R>>
|
||||
ranges::prev_permutation(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20
|
||||
|
||||
template<class I>
|
||||
using next_permutation_result = in_found_result<I>; // Since C++20
|
||||
|
||||
template<bidirectional_iterator I, sentinel_for<I> S, class Comp = ranges::less,
|
||||
class Proj = identity>
|
||||
requires sortable<I, Comp, Proj>
|
||||
constexpr ranges::next_permutation_result<I>
|
||||
ranges::next_permutation(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20
|
||||
|
||||
template<bidirectional_range R, class Comp = ranges::less,
|
||||
class Proj = identity>
|
||||
requires sortable<iterator_t<R>, Comp, Proj>
|
||||
constexpr ranges::next_permutation_result<borrowed_iterator_t<R>>
|
||||
ranges::next_permutation(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20
|
||||
|
||||
}
|
||||
|
||||
template <class InputIterator, class Predicate>
|
||||
constexpr bool // constexpr in C++20
|
||||
all_of(InputIterator first, InputIterator last, Predicate pred);
|
||||
|
||||
@ -1587,6 +1784,7 @@ template <class BidirectionalIterator, class Compare>
|
||||
#include <__algorithm/ranges_all_of.h>
|
||||
#include <__algorithm/ranges_any_of.h>
|
||||
#include <__algorithm/ranges_binary_search.h>
|
||||
#include <__algorithm/ranges_clamp.h>
|
||||
#include <__algorithm/ranges_copy.h>
|
||||
#include <__algorithm/ranges_copy_backward.h>
|
||||
#include <__algorithm/ranges_copy_if.h>
|
||||
@ -1607,9 +1805,11 @@ template <class BidirectionalIterator, class Compare>
|
||||
#include <__algorithm/ranges_generate.h>
|
||||
#include <__algorithm/ranges_generate_n.h>
|
||||
#include <__algorithm/ranges_includes.h>
|
||||
#include <__algorithm/ranges_inplace_merge.h>
|
||||
#include <__algorithm/ranges_is_heap.h>
|
||||
#include <__algorithm/ranges_is_heap_until.h>
|
||||
#include <__algorithm/ranges_is_partitioned.h>
|
||||
#include <__algorithm/ranges_is_permutation.h>
|
||||
#include <__algorithm/ranges_is_sorted.h>
|
||||
#include <__algorithm/ranges_is_sorted_until.h>
|
||||
#include <__algorithm/ranges_lexicographical_compare.h>
|
||||
@ -1625,21 +1825,30 @@ template <class BidirectionalIterator, class Compare>
|
||||
#include <__algorithm/ranges_mismatch.h>
|
||||
#include <__algorithm/ranges_move.h>
|
||||
#include <__algorithm/ranges_move_backward.h>
|
||||
#include <__algorithm/ranges_next_permutation.h>
|
||||
#include <__algorithm/ranges_none_of.h>
|
||||
#include <__algorithm/ranges_nth_element.h>
|
||||
#include <__algorithm/ranges_partial_sort.h>
|
||||
#include <__algorithm/ranges_partial_sort_copy.h>
|
||||
#include <__algorithm/ranges_partition.h>
|
||||
#include <__algorithm/ranges_partition_copy.h>
|
||||
#include <__algorithm/ranges_partition_point.h>
|
||||
#include <__algorithm/ranges_pop_heap.h>
|
||||
#include <__algorithm/ranges_prev_permutation.h>
|
||||
#include <__algorithm/ranges_push_heap.h>
|
||||
#include <__algorithm/ranges_remove.h>
|
||||
#include <__algorithm/ranges_remove_copy.h>
|
||||
#include <__algorithm/ranges_remove_copy_if.h>
|
||||
#include <__algorithm/ranges_remove_if.h>
|
||||
#include <__algorithm/ranges_replace.h>
|
||||
#include <__algorithm/ranges_replace_copy.h>
|
||||
#include <__algorithm/ranges_replace_copy_if.h>
|
||||
#include <__algorithm/ranges_replace_if.h>
|
||||
#include <__algorithm/ranges_reverse.h>
|
||||
#include <__algorithm/ranges_reverse_copy.h>
|
||||
#include <__algorithm/ranges_rotate.h>
|
||||
#include <__algorithm/ranges_rotate_copy.h>
|
||||
#include <__algorithm/ranges_sample.h>
|
||||
#include <__algorithm/ranges_search.h>
|
||||
#include <__algorithm/ranges_search_n.h>
|
||||
#include <__algorithm/ranges_set_difference.h>
|
||||
@ -1653,6 +1862,8 @@ template <class BidirectionalIterator, class Compare>
|
||||
#include <__algorithm/ranges_stable_sort.h>
|
||||
#include <__algorithm/ranges_swap_ranges.h>
|
||||
#include <__algorithm/ranges_transform.h>
|
||||
#include <__algorithm/ranges_unique.h>
|
||||
#include <__algorithm/ranges_unique_copy.h>
|
||||
#include <__algorithm/ranges_upper_bound.h>
|
||||
#include <__algorithm/remove.h>
|
||||
#include <__algorithm/remove_copy.h>
|
||||
|
@ -23,16 +23,23 @@ namespace std {
|
||||
using format_args = basic_format_args<format_context>;
|
||||
using wformat_args = basic_format_args<wformat_context>;
|
||||
|
||||
// [format.fmt.string], class template basic-format-string
|
||||
// [format.fmt.string], class template basic_format_string
|
||||
template<class charT, class... Args>
|
||||
struct basic-format-string; // exposition only
|
||||
struct basic_format_string { // since C++23, exposition only before C++23
|
||||
private:
|
||||
basic_string_view<charT> str; // exposition only
|
||||
|
||||
public:
|
||||
template<class T> consteval basic_format_string(const T& s);
|
||||
|
||||
constexpr basic_string_view<charT> get() const noexcept { return str; }
|
||||
};
|
||||
template<class... Args>
|
||||
using format-string = // exposition only
|
||||
basic-format-string<char, type_identity_t<Args>...>;
|
||||
using format_string = // since C++23, exposition only before C++23
|
||||
basic_format_string<char, type_identity_t<Args>...>;
|
||||
template<class... Args>
|
||||
using wformat-string = // exposition only
|
||||
basic-format-string<wchar_t, type_identity_t<Args>...>;
|
||||
using wformat_string = // since C++23, exposition only before C++23
|
||||
basic_format_string<wchar_t, type_identity_t<Args>...>;
|
||||
|
||||
// [format.functions], formatting functions
|
||||
template<class... Args>
|
||||
@ -233,7 +240,7 @@ private:
|
||||
};
|
||||
|
||||
// Dummy format_context only providing the parts used during constant
|
||||
// validation of the basic-format-string.
|
||||
// validation of the basic_format_string.
|
||||
template <class _CharT>
|
||||
struct _LIBCPP_TEMPLATE_VIS __compile_time_basic_format_context {
|
||||
public:
|
||||
@ -468,17 +475,21 @@ __vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) {
|
||||
} // namespace __format
|
||||
|
||||
template <class _CharT, class... _Args>
|
||||
struct _LIBCPP_TEMPLATE_VIS __basic_format_string {
|
||||
basic_string_view<_CharT> __str_;
|
||||
|
||||
struct _LIBCPP_TEMPLATE_VIS basic_format_string {
|
||||
template <class _Tp>
|
||||
requires convertible_to<const _Tp&, basic_string_view<_CharT>>
|
||||
consteval __basic_format_string(const _Tp& __str) : __str_{__str} {
|
||||
consteval basic_format_string(const _Tp& __str) : __str_{__str} {
|
||||
__format::__vformat_to(basic_format_parse_context<_CharT>{__str_, sizeof...(_Args)},
|
||||
_Context{__types_.data(), __handles_.data(), sizeof...(_Args)});
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT constexpr basic_string_view<_CharT> get() const noexcept {
|
||||
return __str_;
|
||||
}
|
||||
|
||||
private:
|
||||
basic_string_view<_CharT> __str_;
|
||||
|
||||
using _Context = __format::__compile_time_basic_format_context<_CharT>;
|
||||
|
||||
static constexpr array<__format::__arg_t, sizeof...(_Args)> __types_{
|
||||
@ -510,11 +521,11 @@ private:
|
||||
};
|
||||
|
||||
template <class... _Args>
|
||||
using __format_string_t = __basic_format_string<char, type_identity_t<_Args>...>;
|
||||
using format_string = basic_format_string<char, type_identity_t<_Args>...>;
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
template <class... _Args>
|
||||
using __wformat_string_t = __basic_format_string<wchar_t, type_identity_t<_Args>...>;
|
||||
using wformat_string = basic_format_string<wchar_t, type_identity_t<_Args>...>;
|
||||
#endif
|
||||
|
||||
template <class _OutIt, class _CharT, class _FormatOutIt>
|
||||
@ -555,16 +566,16 @@ vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) {
|
||||
|
||||
template <output_iterator<const char&> _OutIt, class... _Args>
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
|
||||
format_to(_OutIt __out_it, __format_string_t<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.__str_,
|
||||
format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(),
|
||||
_VSTD::make_format_args(__args...));
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
|
||||
format_to(_OutIt __out_it, __wformat_string_t<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.__str_,
|
||||
format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(),
|
||||
_VSTD::make_wformat_args(__args...));
|
||||
}
|
||||
#endif
|
||||
@ -586,16 +597,16 @@ vformat(wstring_view __fmt, wformat_args __args) {
|
||||
#endif
|
||||
|
||||
template <class... _Args>
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(__format_string_t<_Args...> __fmt,
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(format_string<_Args...> __fmt,
|
||||
_Args&&... __args) {
|
||||
return _VSTD::vformat(__fmt.__str_, _VSTD::make_format_args(__args...));
|
||||
return _VSTD::vformat(__fmt.get(), _VSTD::make_format_args(__args...));
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
template <class... _Args>
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
|
||||
format(__wformat_string_t<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::vformat(__fmt.__str_, _VSTD::make_wformat_args(__args...));
|
||||
format(wformat_string<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::vformat(__fmt.get(), _VSTD::make_wformat_args(__args...));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -611,16 +622,16 @@ _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it,
|
||||
|
||||
template <output_iterator<const char&> _OutIt, class... _Args>
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
|
||||
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, __format_string_t<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, __fmt.__str_, _VSTD::make_format_args(__args...));
|
||||
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, format_string<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_format_args(__args...));
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
|
||||
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, __wformat_string_t<_Args...> __fmt,
|
||||
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wformat_string<_Args...> __fmt,
|
||||
_Args&&... __args) {
|
||||
return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, __fmt.__str_, _VSTD::make_wformat_args(__args...));
|
||||
return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_wformat_args(__args...));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -634,15 +645,15 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt,
|
||||
|
||||
template <class... _Args>
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
|
||||
formatted_size(__format_string_t<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::__vformatted_size(__fmt.__str_, basic_format_args{_VSTD::make_format_args(__args...)});
|
||||
formatted_size(format_string<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)});
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
template <class... _Args>
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
|
||||
formatted_size(__wformat_string_t<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::__vformatted_size(__fmt.__str_, basic_format_args{_VSTD::make_wformat_args(__args...)});
|
||||
formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)});
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -686,16 +697,16 @@ _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt v
|
||||
|
||||
template <output_iterator<const char&> _OutIt, class... _Args>
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
|
||||
format_to(_OutIt __out_it, locale __loc, __format_string_t<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.__str_,
|
||||
format_to(_OutIt __out_it, locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(),
|
||||
_VSTD::make_format_args(__args...));
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
|
||||
format_to(_OutIt __out_it, locale __loc, __wformat_string_t<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.__str_,
|
||||
format_to(_OutIt __out_it, locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(),
|
||||
_VSTD::make_wformat_args(__args...));
|
||||
}
|
||||
#endif
|
||||
@ -720,17 +731,17 @@ vformat(locale __loc, wstring_view __fmt, wformat_args __args) {
|
||||
|
||||
template <class... _Args>
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(locale __loc,
|
||||
__format_string_t<_Args...> __fmt,
|
||||
format_string<_Args...> __fmt,
|
||||
_Args&&... __args) {
|
||||
return _VSTD::vformat(_VSTD::move(__loc), __fmt.__str_,
|
||||
return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(),
|
||||
_VSTD::make_format_args(__args...));
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
template <class... _Args>
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
|
||||
format(locale __loc, __wformat_string_t<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::vformat(_VSTD::move(__loc), __fmt.__str_,
|
||||
format(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(),
|
||||
_VSTD::make_wformat_args(__args...));
|
||||
}
|
||||
#endif
|
||||
@ -748,18 +759,18 @@ _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it,
|
||||
|
||||
template <output_iterator<const char&> _OutIt, class... _Args>
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
|
||||
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, __format_string_t<_Args...> __fmt,
|
||||
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, format_string<_Args...> __fmt,
|
||||
_Args&&... __args) {
|
||||
return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.__str_,
|
||||
return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(),
|
||||
_VSTD::make_format_args(__args...));
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
|
||||
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, __wformat_string_t<_Args...> __fmt,
|
||||
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, wformat_string<_Args...> __fmt,
|
||||
_Args&&... __args) {
|
||||
return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.__str_,
|
||||
return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(),
|
||||
_VSTD::make_wformat_args(__args...));
|
||||
}
|
||||
#endif
|
||||
@ -775,15 +786,15 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_
|
||||
|
||||
template <class... _Args>
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
|
||||
formatted_size(locale __loc, __format_string_t<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.__str_, basic_format_args{_VSTD::make_format_args(__args...)});
|
||||
formatted_size(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)});
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
template <class... _Args>
|
||||
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
|
||||
formatted_size(locale __loc, __wformat_string_t<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.__str_, basic_format_args{_VSTD::make_wformat_args(__args...)});
|
||||
formatted_size(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
|
||||
return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)});
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user