diff --git a/contrib/llvm-project/FREEBSD-Xlist b/contrib/llvm-project/FREEBSD-Xlist index a1b16e75a5b8..4f1ddd272910 100644 --- a/contrib/llvm-project/FREEBSD-Xlist +++ b/contrib/llvm-project/FREEBSD-Xlist @@ -41,6 +41,7 @@ clang/lib/AST/CMakeLists.txt clang/lib/ASTMatchers/CMakeLists.txt clang/lib/ASTMatchers/Dynamic/CMakeLists.txt clang/lib/Analysis/CMakeLists.txt +clang/lib/Analysis/FlowSensitive/CMakeLists.txt clang/lib/Analysis/plugins/CMakeLists.txt clang/lib/Analysis/plugins/CheckerDependencyHandling/CMakeLists.txt clang/lib/Analysis/plugins/CheckerOptionHandling/CMakeLists.txt @@ -398,6 +399,7 @@ lldb/source/Plugins/Platform/MacOSX/ lldb/source/Plugins/Platform/NetBSD/CMakeLists.txt lldb/source/Plugins/Platform/OpenBSD/CMakeLists.txt lldb/source/Plugins/Platform/POSIX/CMakeLists.txt +lldb/source/Plugins/Platform/QemuUser/CMakeLists.txt lldb/source/Plugins/Platform/Windows/ lldb/source/Plugins/Platform/gdb-server/CMakeLists.txt lldb/source/Plugins/Process/CMakeLists.txt diff --git a/contrib/llvm-project/clang/include/clang/AST/Decl.h b/contrib/llvm-project/clang/include/clang/AST/Decl.h index cc0e8de7c071..2c92571325c8 100644 --- a/contrib/llvm-project/clang/include/clang/AST/Decl.h +++ b/contrib/llvm-project/clang/include/clang/AST/Decl.h @@ -1837,7 +1837,8 @@ enum class MultiVersionKind { None, Target, CPUSpecific, - CPUDispatch + CPUDispatch, + TargetClones }; /// Represents a function declaration or definition. @@ -2456,6 +2457,10 @@ class FunctionDecl : public DeclaratorDecl, /// the target functionality. bool isTargetMultiVersion() const; + /// True if this function is a multiversioned dispatch function as a part of + /// the target-clones functionality. + bool isTargetClonesMultiVersion() const; + /// \brief Get the associated-constraints of this function declaration. /// Currently, this will either be a vector of size 1 containing the /// trailing-requires-clause or an empty vector. diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclBase.h b/contrib/llvm-project/clang/include/clang/AST/DeclBase.h index 18468c8ca1c4..2a0a19597391 100644 --- a/contrib/llvm-project/clang/include/clang/AST/DeclBase.h +++ b/contrib/llvm-project/clang/include/clang/AST/DeclBase.h @@ -352,7 +352,7 @@ class alignas(8) Decl { DeclContext *Parent, std::size_t Extra = 0); private: - bool AccessDeclContextSanity() const; + bool AccessDeclContextCheck() const; /// Get the module ownership kind to use for a local lexical child of \p DC, /// which may be either a local or (rarely) an imported declaration. @@ -472,11 +472,11 @@ class alignas(8) Decl { void setAccess(AccessSpecifier AS) { Access = AS; - assert(AccessDeclContextSanity()); + assert(AccessDeclContextCheck()); } AccessSpecifier getAccess() const { - assert(AccessDeclContextSanity()); + assert(AccessDeclContextCheck()); return AccessSpecifier(Access); } diff --git a/contrib/llvm-project/clang/include/clang/AST/Expr.h b/contrib/llvm-project/clang/include/clang/AST/Expr.h index 5d42e5284a56..02469e3a8cae 100644 --- a/contrib/llvm-project/clang/include/clang/AST/Expr.h +++ b/contrib/llvm-project/clang/include/clang/AST/Expr.h @@ -6304,8 +6304,10 @@ class AtomicExpr : public Expr { bool isCmpXChg() const { return getOp() == AO__c11_atomic_compare_exchange_strong || getOp() == AO__c11_atomic_compare_exchange_weak || + getOp() == AO__hip_atomic_compare_exchange_strong || getOp() == AO__opencl_atomic_compare_exchange_strong || getOp() == AO__opencl_atomic_compare_exchange_weak || + getOp() == AO__hip_atomic_compare_exchange_weak || getOp() == AO__atomic_compare_exchange || getOp() == AO__atomic_compare_exchange_n; } @@ -6340,6 +6342,8 @@ class AtomicExpr : public Expr { auto Kind = (Op >= AO__opencl_atomic_load && Op <= AO__opencl_atomic_fetch_max) ? AtomicScopeModelKind::OpenCL + : (Op >= AO__hip_atomic_load && Op <= AO__hip_atomic_fetch_max) + ? AtomicScopeModelKind::HIP : AtomicScopeModelKind::None; return AtomicScopeModel::create(Kind); } diff --git a/contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h b/contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h index 8cb56fb4ae90..88abba28c991 100644 --- a/contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h +++ b/contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h @@ -18,6 +18,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclOpenMP.h" +#include "clang/AST/DeclTemplate.h" #include "clang/Basic/ABI.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMapInfo.h" @@ -129,8 +130,12 @@ class GlobalDecl { } KernelReferenceKind getKernelReferenceKind() const { - assert(isa(getDecl()) && - cast(getDecl())->hasAttr() && + assert(((isa(getDecl()) && + cast(getDecl())->hasAttr()) || + (isa(getDecl()) && + cast(getDecl()) + ->getTemplatedDecl() + ->hasAttr())) && "Decl is not a GPU kernel!"); return static_cast(Value.getInt()); } diff --git a/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h b/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h index d6e5b215462b..5221d05477d0 100644 --- a/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -4227,8 +4227,8 @@ AST_MATCHER(VarDecl, isInitCapture) { return Node.isInitCapture(); } /// lambdaExpr(forEachLambdaCapture( /// lambdaCapture(capturesVar(varDecl(hasType(isInteger())))))) /// will trigger two matches, binding for 'x' and 'y' respectively. -AST_MATCHER_P(LambdaExpr, forEachLambdaCapture, LambdaCaptureMatcher, - InnerMatcher) { +AST_MATCHER_P(LambdaExpr, forEachLambdaCapture, + internal::Matcher, InnerMatcher) { BoundNodesTreeBuilder Result; bool Matched = false; for (const auto &Capture : Node.captures()) { @@ -4655,7 +4655,8 @@ extern const internal::VariadicAllOfMatcher lambdaCapture; /// lambdaExpr(hasAnyCapture(lambdaCapture())) and /// lambdaExpr(hasAnyCapture(lambdaCapture(refersToVarDecl(hasName("t"))))) /// both match `[=](){ return t; }`. -AST_MATCHER_P(LambdaExpr, hasAnyCapture, LambdaCaptureMatcher, InnerMatcher) { +AST_MATCHER_P(LambdaExpr, hasAnyCapture, internal::Matcher, + InnerMatcher) { for (const LambdaCapture &Capture : Node.captures()) { clang::ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder); if (InnerMatcher.matches(Capture, Finder, &Result)) { diff --git a/contrib/llvm-project/clang/include/clang/Analysis/CFG.h b/contrib/llvm-project/clang/include/clang/Analysis/CFG.h index 3b9b22e87f35..b8e453fcc235 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/CFG.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/CFG.h @@ -515,7 +515,7 @@ class CFGTerminator { /// of the most derived class while we're in the base class. VirtualBaseBranch, - /// Number of different kinds, for validity checks. We subtract 1 so that + /// Number of different kinds, for assertions. We subtract 1 so that /// to keep receiving compiler warnings when we don't cover all enum values /// in a switch. NumKindsMinusOne = VirtualBaseBranch diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h new file mode 100644 index 000000000000..a5d4a5d6ba40 --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h @@ -0,0 +1,134 @@ +//===- DataflowAnalysis.h ---------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines base types and functions for building dataflow analyses +// that run over Control-Flow Graphs (CFGs). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWANALYSIS_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWANALYSIS_H + +#include +#include +#include + +#include "clang/AST/ASTContext.h" +#include "clang/AST/Stmt.h" +#include "clang/Analysis/CFG.h" +#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" +#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h" +#include "llvm/ADT/Any.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" + +namespace clang { +namespace dataflow { + +/// Base class template for dataflow analyses built on a single lattice type. +/// +/// Requirements: +/// +/// `Derived` must be derived from a specialization of this class template and +/// must provide the following public members: +/// * `LatticeT initialElement()` - returns a lattice element that models the +/// initial state of a basic block; +/// * `LatticeT transfer(const Stmt *, const LatticeT &, Environment &)` - +/// applies the analysis transfer function for a given statement and lattice +/// element. +/// +/// `LatticeT` is a bounded join-semilattice that is used by `Derived` and must +/// provide the following public members: +/// * `LatticeJoinEffect join(const LatticeT &)` - joins the object and the +/// argument by computing their least upper bound, modifies the object if +/// necessary, and returns an effect indicating whether any changes were +/// made to it; +/// * `bool operator==(const LatticeT &) const` - returns true if and only if +/// the object is equal to the argument. +template +class DataflowAnalysis : public TypeErasedDataflowAnalysis { +public: + /// Bounded join-semilattice that is used in the analysis. + using Lattice = LatticeT; + + explicit DataflowAnalysis(ASTContext &Context) : Context(Context) {} + + ASTContext &getASTContext() final { return Context; } + + TypeErasedLattice typeErasedInitialElement() final { + return {static_cast(this)->initialElement()}; + } + + LatticeJoinEffect joinTypeErased(TypeErasedLattice &E1, + const TypeErasedLattice &E2) final { + Lattice &L1 = llvm::any_cast(E1.Value); + const Lattice &L2 = llvm::any_cast(E2.Value); + return L1.join(L2); + } + + bool isEqualTypeErased(const TypeErasedLattice &E1, + const TypeErasedLattice &E2) final { + const Lattice &L1 = llvm::any_cast(E1.Value); + const Lattice &L2 = llvm::any_cast(E2.Value); + return L1 == L2; + } + + TypeErasedLattice transferTypeErased(const Stmt *Stmt, + const TypeErasedLattice &E, + Environment &Env) final { + const Lattice &L = llvm::any_cast(E.Value); + return {static_cast(this)->transfer(Stmt, L, Env)}; + } + +private: + ASTContext &Context; +}; + +// Model of the program at a given program point. +template struct DataflowAnalysisState { + // Model of a program property. + LatticeT Lattice; + + // Model of the state of the program (store and heap). + Environment Env; +}; + +/// Performs dataflow analysis and returns a mapping from basic block IDs to +/// dataflow analysis states that model the respective basic blocks. Indices +/// of the returned vector correspond to basic block IDs. +/// +/// Requirements: +/// +/// `Cfg` must have been built with `CFG::BuildOptions::setAllAlwaysAdd()` to +/// ensure that all sub-expressions in a basic block are evaluated. +template +std::vector>> +runDataflowAnalysis(const CFG &Cfg, AnalysisT &Analysis, + const Environment &InitEnv) { + auto TypeErasedBlockStates = + runTypeErasedDataflowAnalysis(Cfg, Analysis, InitEnv); + std::vector< + llvm::Optional>> + BlockStates; + BlockStates.reserve(TypeErasedBlockStates.size()); + llvm::transform(std::move(TypeErasedBlockStates), + std::back_inserter(BlockStates), [](auto &OptState) { + return std::move(OptState).map([](auto &&State) { + return DataflowAnalysisState{ + llvm::any_cast( + std::move(State.Lattice.Value)), + std::move(State.Env)}; + }); + }); + return BlockStates; +} + +} // namespace dataflow +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWANALYSIS_H diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h new file mode 100644 index 000000000000..69a5c2e47b66 --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -0,0 +1,27 @@ +//===-- DataflowEnvironment.h -----------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines an Environment class that is used by dataflow analyses +// that run over Control-Flow Graphs (CFGs) to keep track of the state of the +// program at given program points. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H + +namespace clang { +namespace dataflow { + +/// Holds the state of the program (store and heap) at a given program point. +class Environment {}; + +} // namespace dataflow +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowLattice.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowLattice.h new file mode 100644 index 000000000000..37d2e0200410 --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowLattice.h @@ -0,0 +1,29 @@ +//===- DataflowLattice.h ----------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines base types for building lattices to be used in dataflow +// analyses that run over Control-Flow Graphs (CFGs). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWLATTICE_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWLATTICE_H + +namespace clang { +namespace dataflow { + +/// Effect indicating whether a lattice join operation resulted in a new value. +enum class LatticeJoinEffect { + Unchanged, + Changed, +}; + +} // namespace dataflow +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWLATTICE_H diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h new file mode 100644 index 000000000000..9448b911f471 --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h @@ -0,0 +1,95 @@ +//===- TypeErasedDataflowAnalysis.h -----------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines type-erased base types and functions for building dataflow +// analyses that run over Control-Flow Graphs (CFGs). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TYPEERASEDDATAFLOWANALYSIS_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TYPEERASEDDATAFLOWANALYSIS_H + +#include + +#include "clang/AST/ASTContext.h" +#include "clang/AST/Stmt.h" +#include "clang/Analysis/CFG.h" +#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" +#include "clang/Analysis/FlowSensitive/DataflowLattice.h" +#include "llvm/ADT/Any.h" +#include "llvm/ADT/Optional.h" + +namespace clang { +namespace dataflow { + +/// Type-erased lattice element container. +/// +/// Requirements: +/// +/// The type of the object stored in the container must be a bounded +/// join-semilattice. +struct TypeErasedLattice { + llvm::Any Value; +}; + +/// Type-erased base class for dataflow analyses built on a single lattice type. +class TypeErasedDataflowAnalysis { +public: + virtual ~TypeErasedDataflowAnalysis() {} + + /// Returns the `ASTContext` that is used by the analysis. + virtual ASTContext &getASTContext() = 0; + + /// Returns a type-erased lattice element that models the initial state of a + /// basic block. + virtual TypeErasedLattice typeErasedInitialElement() = 0; + + /// Joins two type-erased lattice elements by computing their least upper + /// bound. Places the join result in the left element and returns an effect + /// indicating whether any changes were made to it. + virtual LatticeJoinEffect joinTypeErased(TypeErasedLattice &, + const TypeErasedLattice &) = 0; + + /// Returns true if and only if the two given type-erased lattice elements are + /// equal. + virtual bool isEqualTypeErased(const TypeErasedLattice &, + const TypeErasedLattice &) = 0; + + /// Applies the analysis transfer function for a given statement and + /// type-erased lattice element. + virtual TypeErasedLattice transferTypeErased(const Stmt *, + const TypeErasedLattice &, + Environment &) = 0; +}; + +/// Type-erased model of the program at a given program point. +struct TypeErasedDataflowAnalysisState { + /// Type-erased model of a program property. + TypeErasedLattice Lattice; + + /// Model of the state of the program (store and heap). + Environment Env; +}; + +/// Performs dataflow analysis and returns a mapping from basic block IDs to +/// dataflow analysis states that model the respective basic blocks. Indices +/// of the returned vector correspond to basic block IDs. +/// +/// Requirements: +/// +/// `Cfg` must have been built with `CFG::BuildOptions::setAllAlwaysAdd()` to +/// ensure that all sub-expressions in a basic block are evaluated. +std::vector> +runTypeErasedDataflowAnalysis(const CFG &Cfg, + TypeErasedDataflowAnalysis &Analysis, + const Environment &InitEnv); + +} // namespace dataflow +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TYPEERASEDDATAFLOWANALYSIS_H diff --git a/contrib/llvm-project/clang/include/clang/Basic/Attr.td b/contrib/llvm-project/clang/include/clang/Basic/Attr.td index 39588d94cf09..fab3f3edfb83 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/Attr.td +++ b/contrib/llvm-project/clang/include/clang/Basic/Attr.td @@ -2677,6 +2677,40 @@ def Target : InheritableAttr { }]; } +def TargetClones : InheritableAttr { + let Spellings = [GCC<"target_clones">]; + let Args = [VariadicStringArgument<"featuresStrs">]; + let Documentation = [TargetClonesDocs]; + let Subjects = SubjectList<[Function], ErrorDiag>; + let AdditionalMembers = [{ + StringRef getFeatureStr(unsigned Index) const { + return *(featuresStrs_begin() + Index); + } + // 'default' is always moved to the end, so it isn't considered + // when mangling the index. + unsigned getMangledIndex(unsigned Index) const { + if (getFeatureStr(Index) == "default") + return std::count_if(featuresStrs_begin(), featuresStrs_end(), + [](StringRef S) { return S != "default"; }); + + return std::count_if(featuresStrs_begin(), featuresStrs_begin() + Index, + [](StringRef S) { return S != "default"; }); + } + + // True if this is the first of this version to appear in the config string. + // This is used to make sure we don't try to emit this function multiple + // times. + bool isFirstOfVersion(unsigned Index) const { + StringRef FeatureStr(getFeatureStr(Index)); + return 0 == std::count_if( + featuresStrs_begin(), featuresStrs_begin() + Index, + [FeatureStr](StringRef S) { return S == FeatureStr; }); + } + }]; +} + +def : MutualExclusions<[TargetClones, Target, CPUDispatch, CPUSpecific]>; + def MinVectorWidth : InheritableAttr { let Spellings = [Clang<"min_vector_width">]; let Args = [UnsignedArgument<"VectorWidth">]; diff --git a/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td b/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td index e7afb3699eb1..10cce4c2d689 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td +++ b/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td @@ -2233,6 +2233,40 @@ Additionally, a function may not become multiversioned after its first use. }]; } +def TargetClonesDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the ``target_clones("OPTIONS")`` attribute. This attribute may be +attached to a function declaration and causes function multiversioning, where +multiple versions of the function will be emitted with different code +generation options. Additionally, these versions will be resolved at runtime +based on the priority of their attribute options. All ``target_clone`` functions +are considered multiversioned functions. + +All multiversioned functions must contain a ``default`` (fallback) +implementation, otherwise usages of the function are considered invalid. +Additionally, a function may not become multiversioned after its first use. + +The options to ``target_clones`` can either be a target-specific architecture +(specified as ``arch=CPU``), or one of a list of subtarget features. + +Example "subtarget features" from the x86 backend include: "mmx", "sse", "sse4.2", +"avx", "xop" and largely correspond to the machine specific options handled by +the front end. + +The versions can either be listed as a comma-separated sequence of string +literals or as a single string literal containing a comma-separated list of +versions. For compatibility with GCC, the two formats can be mixed. For +example, the following will emit 4 versions of the function: + + .. code-block:: c++ + + __attribute__((target_clones("arch=atom,avx2","arch=ivybridge","default"))) + void foo() {} + +}]; +} + def MinVectorWidthDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/contrib/llvm-project/clang/include/clang/Basic/Builtins.def b/contrib/llvm-project/clang/include/clang/Basic/Builtins.def index b05777889e79..ad8b66aa490b 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/Builtins.def +++ b/contrib/llvm-project/clang/include/clang/Basic/Builtins.def @@ -854,6 +854,19 @@ ATOMIC_BUILTIN(__opencl_atomic_fetch_max, "v.", "t") ATOMIC_BUILTIN(__atomic_fetch_min, "v.", "t") ATOMIC_BUILTIN(__atomic_fetch_max, "v.", "t") +// HIP atomic builtins. +ATOMIC_BUILTIN(__hip_atomic_load, "v.", "t") +ATOMIC_BUILTIN(__hip_atomic_store, "v.", "t") +ATOMIC_BUILTIN(__hip_atomic_compare_exchange_weak, "v.", "t") +ATOMIC_BUILTIN(__hip_atomic_compare_exchange_strong, "v.", "t") +ATOMIC_BUILTIN(__hip_atomic_exchange, "v.", "t") +ATOMIC_BUILTIN(__hip_atomic_fetch_add, "v.", "t") +ATOMIC_BUILTIN(__hip_atomic_fetch_and, "v.", "t") +ATOMIC_BUILTIN(__hip_atomic_fetch_or, "v.", "t") +ATOMIC_BUILTIN(__hip_atomic_fetch_xor, "v.", "t") +ATOMIC_BUILTIN(__hip_atomic_fetch_min, "v.", "t") +ATOMIC_BUILTIN(__hip_atomic_fetch_max, "v.", "t") + #undef ATOMIC_BUILTIN // Non-overloaded atomic builtins. diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsPPC.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsPPC.def index cd6b2df10e52..70b0184f199f 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsPPC.def +++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsPPC.def @@ -404,6 +404,7 @@ BUILTIN(__builtin_altivec_vbpermd, "V2ULLiV2ULLiV16Uc", "") // P8 Crypto built-ins. BUILTIN(__builtin_altivec_crypto_vsbox, "V2ULLiV2ULLi", "") BUILTIN(__builtin_altivec_crypto_vpermxor, "V16UcV16UcV16UcV16Uc", "") +BUILTIN(__builtin_altivec_crypto_vpermxor_be, "V16UcV16UcV16UcV16Uc", "") BUILTIN(__builtin_altivec_crypto_vshasigmaw, "V4UiV4UiIiIi", "") BUILTIN(__builtin_altivec_crypto_vshasigmad, "V2ULLiV2ULLiIiIi", "") BUILTIN(__builtin_altivec_crypto_vcipher, "V2ULLiV2ULLiV2ULLi", "") @@ -424,6 +425,12 @@ BUILTIN(__builtin_altivec_vctzh, "V8UsV8Us", "") BUILTIN(__builtin_altivec_vctzw, "V4UiV4Ui", "") BUILTIN(__builtin_altivec_vctzd, "V2ULLiV2ULLi", "") +// P8 BCD builtins. +BUILTIN(__builtin_ppc_bcdadd, "V16UcV16UcV16UcIi", "") +BUILTIN(__builtin_ppc_bcdsub, "V16UcV16UcV16UcIi", "") +BUILTIN(__builtin_ppc_bcdadd_p, "iiV16UcV16Uc", "") +BUILTIN(__builtin_ppc_bcdsub_p, "iiV16UcV16Uc", "") + BUILTIN(__builtin_altivec_vclzlsbb, "SiV16Uc", "") BUILTIN(__builtin_altivec_vctzlsbb, "SiV16Uc", "") BUILTIN(__builtin_altivec_vprtybw, "V4UiV4Ui", "") diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td index ff8c36910e13..2f50918b527b 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -189,6 +189,12 @@ def err_drv_invalid_mtp : Error< "invalid thread pointer reading mode '%0'">; def err_drv_missing_arg_mtp : Error< "missing argument to '%0'">; +def warn_drv_missing_plugin_name : Warning< + "missing plugin name in %0">, + InGroup; +def warn_drv_missing_plugin_arg : Warning< + "missing plugin argument for plugin %0 in %1">, + InGroup; def err_drv_invalid_libcxx_deployment : Error< "invalid deployment target for -stdlib=libc++ (requires %0 or later)">; def err_drv_invalid_argument_to_option : Error< @@ -394,6 +400,8 @@ def warn_ignoring_verify_debuginfo_preserve_export : Warning< InGroup; def err_invalid_branch_protection: Error < "invalid branch protection option '%0' in '%1'">; +def warn_unsupported_branch_protection: Warning < + "invalid branch protection option '%0' in '%1'">, InGroup; def err_invalid_sls_hardening : Error< "invalid sls hardening option '%0' in '%1'">; def err_sls_hardening_arm_not_supported : Error< diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td index 85d373845c81..90df3a424406 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td @@ -56,7 +56,9 @@ def CoroutineMissingUnhandledException : DiagGroup<"coroutine-missing-unhandled-exception">; def DeprecatedExperimentalCoroutine : DiagGroup<"deprecated-experimental-coroutine">; -def Coroutine : DiagGroup<"coroutine", [CoroutineMissingUnhandledException, DeprecatedExperimentalCoroutine]>; +def DeprecatedCoroutine : + DiagGroup<"deprecated-coroutine", [DeprecatedExperimentalCoroutine]>; +def Coroutine : DiagGroup<"coroutine", [CoroutineMissingUnhandledException, DeprecatedCoroutine]>; def ObjCBoolConstantConversion : DiagGroup<"objc-bool-constant-conversion">; def ConstantConversion : DiagGroup<"constant-conversion", [BitFieldConstantConversion, @@ -1273,9 +1275,14 @@ def : DiagGroup<"spirv-compat", [SpirCompat]>; // Alias. // Warning for the GlobalISel options. def GlobalISel : DiagGroup<"global-isel">; +// A warning group for the GNU extension to allow mixed specifier types for +// target-clones multiversioning. +def TargetClonesMixedSpecifiers : DiagGroup<"target-clones-mixed-specifiers">; + // A warning group specifically for warnings related to function // multiversioning. -def FunctionMultiVersioning : DiagGroup<"function-multiversion">; +def FunctionMultiVersioning + : DiagGroup<"function-multiversion", [TargetClonesMixedSpecifiers]>; def NoDeref : DiagGroup<"noderef">; @@ -1331,3 +1338,6 @@ def PedanticMacros : DiagGroup<"pedantic-macros", BuiltinMacroRedefined, RestrictExpansionMacro, FinalMacro]>; + +def BranchProtection : DiagGroup<"branch-protection">; + diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h index aef86516707c..375930c14848 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h @@ -30,7 +30,7 @@ namespace clang { // Size of each of the diagnostic categories. enum { DIAG_SIZE_COMMON = 300, - DIAG_SIZE_DRIVER = 250, + DIAG_SIZE_DRIVER = 300, DIAG_SIZE_FRONTEND = 150, DIAG_SIZE_SERIALIZATION = 120, DIAG_SIZE_LEX = 400, diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticParseKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticParseKinds.td index 1bc2e8b0c7ef..92e877074ad3 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1548,6 +1548,9 @@ def note_meant_to_use_typename : Note< let CategoryName = "Coroutines Issue" in { def err_for_co_await_not_range_for : Error< "'co_await' modifier can only be applied to range-based for loop">; +def warn_deprecated_for_co_await : Warning< + "'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated">, + InGroup; } let CategoryName = "Concepts Issue" in { diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td index dc67f86f25ca..fb5bd53f7432 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2979,9 +2979,13 @@ def err_attribute_requires_opencl_version : Error< "attribute %0 is supported in the OpenCL version %1%select{| onwards}2">; def err_invalid_branch_protection_spec : Error< "invalid or misplaced branch protection specification '%0'">; +def warn_unsupported_branch_protection_spec : Warning< + "unsupported branch protection specification '%0'">, InGroup; + def warn_unsupported_target_attribute : Warning<"%select{unsupported|duplicate|unknown}0%select{| architecture|" - " tune CPU}1 '%2' in the 'target' attribute string; 'target' " + " tune CPU}1 '%2' in the '%select{target|target_clones}3' " + "attribute string; '%select{target|target_clones}3' " "attribute ignored">, InGroup; def err_attribute_unsupported @@ -9864,6 +9868,8 @@ def warn_duplicate_attribute_exact : Warning< def warn_duplicate_attribute : Warning< "attribute %0 is already applied with different arguments">, InGroup; +def err_disallowed_duplicate_attribute : Error< + "attribute %0 cannot appear more than once on a declaration">; def warn_sync_fetch_and_nand_semantics_change : Warning< "the semantics of this intrinsic changed with GCC " @@ -11254,9 +11260,11 @@ def err_multiversion_duplicate : Error< "multiversioned function redeclarations require identical target attributes">; def err_multiversion_noproto : Error< "multiversioned function must have a prototype">; -def err_multiversion_disallowed_other_attr : Error< - "attribute '%select{target|cpu_specific|cpu_dispatch}0' multiversioning cannot be combined" - " with attribute %1">; +def err_multiversion_disallowed_other_attr + : Error<"attribute " + "'%select{|target|cpu_specific|cpu_dispatch|target_clones}0' " + "multiversioning cannot be combined" + " with attribute %1">; def err_multiversion_mismatched_attrs : Error<"attributes on multiversioned functions must all match, attribute " "%0 %select{is missing|has different arguments}1">; @@ -11264,11 +11272,14 @@ def err_multiversion_diff : Error< "multiversioned function declaration has a different %select{calling convention" "|return type|constexpr specification|inline specification|linkage|" "language linkage}0">; -def err_multiversion_doesnt_support : Error< - "attribute '%select{target|cpu_specific|cpu_dispatch}0' multiversioned functions do not " - "yet support %select{function templates|virtual functions|" - "deduced return types|constructors|destructors|deleted functions|" - "defaulted functions|constexpr functions|consteval function}1">; +def err_multiversion_doesnt_support + : Error<"attribute " + "'%select{|target|cpu_specific|cpu_dispatch|target_clones}0' " + "multiversioned functions do not " + "yet support %select{function templates|virtual functions|" + "deduced return types|constructors|destructors|deleted functions|" + "defaulted functions|constexpr functions|consteval " + "function|lambdas}1">; def err_multiversion_not_allowed_on_main : Error< "'main' cannot be a multiversioned function">; def err_multiversion_not_supported : Error< @@ -11285,6 +11296,19 @@ def warn_multiversion_duplicate_entries : Warning< def warn_dispatch_body_ignored : Warning< "body of cpu_dispatch function will be ignored">, InGroup; +def err_target_clone_must_have_default + : Error<"'target_clones' multiversioning requires a default target">; +def err_target_clone_doesnt_match + : Error<"'target_clones' attribute does not match previous declaration">; +def warn_target_clone_mixed_values + : ExtWarn< + "mixing 'target_clones' specifier mechanisms is permitted for GCC " + "compatibility; use a comma separated sequence of string literals, " + "or a string literal containing a comma-separated list of versions">, + InGroup; +def warn_target_clone_duplicate_options + : Warning<"version list contains duplicate entries">, + InGroup; // three-way comparison operator diagnostics def err_implied_comparison_category_type_not_found : Error< diff --git a/contrib/llvm-project/clang/include/clang/Basic/SyncScope.h b/contrib/llvm-project/clang/include/clang/Basic/SyncScope.h index ce8fb9cbed13..34703310af2b 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/SyncScope.h +++ b/contrib/llvm-project/clang/include/clang/Basic/SyncScope.h @@ -40,6 +40,11 @@ namespace clang { /// Update getAsString. /// enum class SyncScope { + HIPSingleThread, + HIPWavefront, + HIPWorkgroup, + HIPAgent, + HIPSystem, OpenCLWorkGroup, OpenCLDevice, OpenCLAllSVMDevices, @@ -49,6 +54,16 @@ enum class SyncScope { inline llvm::StringRef getAsString(SyncScope S) { switch (S) { + case SyncScope::HIPSingleThread: + return "hip_singlethread"; + case SyncScope::HIPWavefront: + return "hip_wavefront"; + case SyncScope::HIPWorkgroup: + return "hip_workgroup"; + case SyncScope::HIPAgent: + return "hip_agent"; + case SyncScope::HIPSystem: + return "hip_system"; case SyncScope::OpenCLWorkGroup: return "opencl_workgroup"; case SyncScope::OpenCLDevice: @@ -62,7 +77,7 @@ inline llvm::StringRef getAsString(SyncScope S) { } /// Defines the kind of atomic scope models. -enum class AtomicScopeModelKind { None, OpenCL }; +enum class AtomicScopeModelKind { None, OpenCL, HIP }; /// Defines the interface for synch scope model. class AtomicScopeModel { @@ -138,6 +153,58 @@ class AtomicScopeOpenCLModel : public AtomicScopeModel { } }; +/// Defines the synch scope model for HIP. +class AtomicScopeHIPModel : public AtomicScopeModel { +public: + /// The enum values match the pre-defined macros + /// __HIP_MEMORY_SCOPE_*, which are used to define memory_scope_* + /// enums in hip-c.h. + enum ID { + SingleThread = 1, + Wavefront = 2, + Workgroup = 3, + Agent = 4, + System = 5, + Last = System + }; + + AtomicScopeHIPModel() {} + + SyncScope map(unsigned S) const override { + switch (static_cast(S)) { + case SingleThread: + return SyncScope::HIPSingleThread; + case Wavefront: + return SyncScope::HIPWavefront; + case Workgroup: + return SyncScope::HIPWorkgroup; + case Agent: + return SyncScope::HIPAgent; + case System: + return SyncScope::HIPSystem; + } + llvm_unreachable("Invalid language synch scope value"); + } + + bool isValid(unsigned S) const override { + return S >= static_cast(SingleThread) && + S <= static_cast(Last); + } + + ArrayRef getRuntimeValues() const override { + static_assert(Last == System, "Does not include all synch scopes"); + static const unsigned Scopes[] = { + static_cast(SingleThread), static_cast(Wavefront), + static_cast(Workgroup), static_cast(Agent), + static_cast(System)}; + return llvm::makeArrayRef(Scopes); + } + + unsigned getFallBackValue() const override { + return static_cast(System); + } +}; + inline std::unique_ptr AtomicScopeModel::create(AtomicScopeModelKind K) { switch (K) { @@ -145,9 +212,11 @@ AtomicScopeModel::create(AtomicScopeModelKind K) { return std::unique_ptr{}; case AtomicScopeModelKind::OpenCL: return std::make_unique(); + case AtomicScopeModelKind::HIP: + return std::make_unique(); } llvm_unreachable("Invalid atomic scope model kind"); } -} +} // namespace clang #endif diff --git a/contrib/llvm-project/clang/include/clang/Driver/Options.td b/contrib/llvm-project/clang/include/clang/Driver/Options.td index 9bde64cf49fd..4e6dd2050344 100644 --- a/contrib/llvm-project/clang/include/clang/Driver/Options.td +++ b/contrib/llvm-project/clang/include/clang/Driver/Options.td @@ -2504,6 +2504,9 @@ defm rwpi : BoolFOption<"rwpi", NegFlag>; def fplugin_EQ : Joined<["-"], "fplugin=">, Group, Flags<[NoXarchOption]>, MetaVarName<"">, HelpText<"Load the named plugin (dynamic shared object)">; +def fplugin_arg : Joined<["-"], "fplugin-arg-">, + MetaVarName<"-">, + HelpText<"Pass to plugin ">; def fpass_plugin_EQ : Joined<["-"], "fpass-plugin=">, Group, Flags<[CC1Option]>, MetaVarName<"">, HelpText<"Load pass plugin from a dynamic shared object file (only with new pass manager).">, @@ -2786,10 +2789,11 @@ def fvisibility_ms_compat : Flag<["-"], "fvisibility-ms-compat">, Group def fvisibility_global_new_delete_hidden : Flag<["-"], "fvisibility-global-new-delete-hidden">, Group, HelpText<"Give global C++ operator new and delete declarations hidden visibility">, Flags<[CC1Option]>, MarshallingInfoFlag>; -def fnew_infallible : Flag<["-"], "fnew-infallible">, Group, - HelpText<"Treats throwing global C++ operator new as always returning valid memory " - "(annotates with __attribute__((returns_nonnull)) and throw()). This is detectable in source.">, - Flags<[CC1Option]>, MarshallingInfoFlag>; +defm new_infallible : BoolFOption<"new-infallible", + LangOpts<"NewInfallible">, DefaultFalse, + PosFlag, NegFlag, + BothFlags<[CC1Option], " treating throwing global C++ operator new as always returning valid memory " + "(annotates with __attribute__((returns_nonnull)) and throw()). This is detectable in source.">>; defm whole_program_vtables : BoolFOption<"whole-program-vtables", CodeGenOpts<"WholeProgramVTables">, DefaultFalse, PosFlag, @@ -4519,7 +4523,7 @@ def frecord_marker_EQ : Joined<["-"], "frecord-marker=">, Group; defm aggressive_function_elimination : BooleanFFlag<"aggressive-function-elimination">, Group; defm align_commons : BooleanFFlag<"align-commons">, Group; defm all_intrinsics : BooleanFFlag<"all-intrinsics">, Group; -defm automatic : BooleanFFlag<"automatic">, Group; +def fautomatic : Flag<["-"], "fautomatic">; // -fno-automatic is significant defm backtrace : BooleanFFlag<"backtrace">, Group; defm bounds_check : BooleanFFlag<"bounds-check">, Group; defm check_array_temporaries : BooleanFFlag<"check-array-temporaries">, Group; @@ -4616,6 +4620,9 @@ defm backslash : OptInFC1FFlag<"backslash", "Specify that backslash in string in defm xor_operator : OptInFC1FFlag<"xor-operator", "Enable .XOR. as a synonym of .NEQV.">; defm logical_abbreviations : OptInFC1FFlag<"logical-abbreviations", "Enable logical abbreviations">; defm implicit_none : OptInFC1FFlag<"implicit-none", "No implicit typing allowed unless overridden by IMPLICIT statements">; + +def fno_automatic : Flag<["-"], "fno-automatic">, Group, + HelpText<"Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE">; } def J : JoinedOrSeparate<["-"], "J">, @@ -5059,9 +5066,10 @@ def msmall_data_limit : Separate<["-"], "msmall-data-limit">, def funwind_tables_EQ : Joined<["-"], "funwind-tables=">, HelpText<"Generate unwinding tables for all functions">, MarshallingInfoInt>; -def mconstructor_aliases : Flag<["-"], "mconstructor-aliases">, - HelpText<"Emit complete constructors and destructors as aliases when possible">, - MarshallingInfoFlag>; +defm constructor_aliases : BoolOption<"m", "constructor-aliases", + CodeGenOpts<"CXXCtorDtorAliases">, DefaultFalse, + PosFlag, NegFlag, + BothFlags<[CC1Option], " emitting complete constructors and destructors as aliases when possible">>; def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">, HelpText<"Link the given bitcode file before performing optimizations.">; def mlink_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">, @@ -5174,10 +5182,6 @@ defm debug_pass_manager : BoolOption<"f", "debug-pass-manager", CodeGenOpts<"DebugPassManager">, DefaultFalse, PosFlag, NegFlag>; -def fexperimental_debug_variable_locations : Flag<["-"], - "fexperimental-debug-variable-locations">, - HelpText<"Use experimental new value-tracking variable locations">, - MarshallingInfoFlag>; def fverify_debuginfo_preserve : Flag<["-"], "fverify-debuginfo-preserve">, HelpText<"Enable Debug Info Metadata preservation testing in " diff --git a/contrib/llvm-project/clang/include/clang/Frontend/PrecompiledPreamble.h b/contrib/llvm-project/clang/include/clang/Frontend/PrecompiledPreamble.h index bb7fd97fe5df..dacbffef0b12 100644 --- a/contrib/llvm-project/clang/include/clang/Frontend/PrecompiledPreamble.h +++ b/contrib/llvm-project/clang/include/clang/Frontend/PrecompiledPreamble.h @@ -274,7 +274,7 @@ class PreambleCallbacks { public: virtual ~PreambleCallbacks() = default; - /// Called before FrontendAction::BeginSourceFile. + /// Called before FrontendAction::Execute. /// Can be used to store references to various CompilerInstance fields /// (e.g. SourceManager) that may be interesting to the consumers of other /// callbacks. @@ -291,7 +291,7 @@ class PreambleCallbacks { /// used instead, but having only this method allows a simpler API. virtual void HandleTopLevelDecl(DeclGroupRef DG); /// Creates wrapper class for PPCallbacks so we can also process information - /// about includes that are inside of a preamble + /// about includes that are inside of a preamble. Called after BeforeExecute. virtual std::unique_ptr createPPCallbacks(); /// The returned CommentHandler will be added to the preprocessor if not null. virtual CommentHandler *getCommentHandler(); diff --git a/contrib/llvm-project/clang/include/clang/Sema/Sema.h b/contrib/llvm-project/clang/include/clang/Sema/Sema.h index 43ce5d983217..1a82a9498d1d 100644 --- a/contrib/llvm-project/clang/include/clang/Sema/Sema.h +++ b/contrib/llvm-project/clang/include/clang/Sema/Sema.h @@ -1296,6 +1296,11 @@ class Sema final { EK_Decltype, EK_TemplateArgument, EK_Other } ExprContext; + // A context can be nested in both a discarded statement context and + // an immediate function context, so they need to be tracked independently. + bool InDiscardedStatement; + bool InImmediateFunctionContext; + ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context, unsigned NumCleanupObjects, CleanupInfo ParentCleanup, @@ -1303,7 +1308,8 @@ class Sema final { ExpressionKind ExprContext) : Context(Context), ParentCleanup(ParentCleanup), NumCleanupObjects(NumCleanupObjects), NumTypos(0), - ManglingContextDecl(ManglingContextDecl), ExprContext(ExprContext) {} + ManglingContextDecl(ManglingContextDecl), ExprContext(ExprContext), + InDiscardedStatement(false), InImmediateFunctionContext(false) {} bool isUnevaluated() const { return Context == ExpressionEvaluationContext::Unevaluated || @@ -1317,7 +1323,13 @@ class Sema final { } bool isImmediateFunctionContext() const { - return Context == ExpressionEvaluationContext::ImmediateFunctionContext; + return Context == ExpressionEvaluationContext::ImmediateFunctionContext || + InImmediateFunctionContext; + } + + bool isDiscardedStatementContext() const { + return Context == ExpressionEvaluationContext::DiscardedStatement || + InDiscardedStatement; } }; @@ -4351,6 +4363,10 @@ class Sema final { llvm::Error isValidSectionSpecifier(StringRef Str); bool checkSectionName(SourceLocation LiteralLoc, StringRef Str); bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str); + bool checkTargetClonesAttrString(SourceLocation LiteralLoc, StringRef Str, + const StringLiteral *Literal, + bool &HasDefault, bool &HasCommas, + SmallVectorImpl &Strings); bool checkMSInheritanceAttrOnDefinition( CXXRecordDecl *RD, SourceRange Range, bool BestCase, MSInheritanceModel SemanticSpelling); @@ -9150,14 +9166,7 @@ class Sema final { bool isImmediateFunctionContext() const { assert(!ExprEvalContexts.empty() && "Must be in an expression evaluation context"); - for (const ExpressionEvaluationContextRecord &context : - llvm::reverse(ExprEvalContexts)) { - if (context.isImmediateFunctionContext()) - return true; - if (context.isUnevaluated()) - return false; - } - return false; + return ExprEvalContexts.back().isImmediateFunctionContext(); } /// RAII class used to determine whether SFINAE has diff --git a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h b/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h index c52da3305f7c..af02fa2e7e87 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h +++ b/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h @@ -195,15 +195,23 @@ class DependencyScanningWorkerFilesystem : public llvm::vfs::ProxyFileSystem { llvm::ErrorOr> openFileForRead(const Twine &Path) override; - void clearIgnoredFiles() { IgnoredFiles.clear(); } - void ignoreFile(StringRef Filename); + /// Disable minimization of the given file. + void disableMinimization(StringRef Filename); + /// Enable minimization of all files. + void enableMinimizationOfAllFiles() { NotToBeMinimized.clear(); } private: - bool shouldIgnoreFile(StringRef Filename); + /// Check whether the file should be minimized. + bool shouldMinimize(StringRef Filename); llvm::ErrorOr getOrCreateFileSystemEntry(const StringRef Filename); + /// Create a cached file system entry based on the initial status result. + CachedFileSystemEntry + createFileSystemEntry(llvm::ErrorOr &&MaybeStatus, + StringRef Filename, bool ShouldMinimize); + /// The global cache shared between worker threads. DependencyScanningFilesystemSharedCache &SharedCache; /// The local cache is used by the worker thread to cache file system queries @@ -214,7 +222,7 @@ class DependencyScanningWorkerFilesystem : public llvm::vfs::ProxyFileSystem { /// currently active preprocessor. ExcludedPreprocessorDirectiveSkipMapping *PPSkipMappings; /// The set of files that should not be minimized. - llvm::StringSet<> IgnoredFiles; + llvm::StringSet<> NotToBeMinimized; }; } // end namespace dependencies diff --git a/contrib/llvm-project/clang/lib/AST/ASTContext.cpp b/contrib/llvm-project/clang/lib/AST/ASTContext.cpp index 221986d8dbab..d72ed2af1491 100644 --- a/contrib/llvm-project/clang/lib/AST/ASTContext.cpp +++ b/contrib/llvm-project/clang/lib/AST/ASTContext.cpp @@ -11798,6 +11798,15 @@ void ASTContext::getFunctionFeatureMap(llvm::StringMap &FeatureMap, Target->getTargetOpts().FeaturesAsWritten.begin(), Target->getTargetOpts().FeaturesAsWritten.end()); Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features); + } else if (const auto *TC = FD->getAttr()) { + std::vector Features; + StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex()); + if (VersionStr.startswith("arch=")) + TargetCPU = VersionStr.drop_front(sizeof("arch=") - 1); + else if (VersionStr != "default") + Features.push_back((StringRef{"+"} + VersionStr).str()); + + Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features); } else { FeatureMap = Target->getTargetOpts().FeatureMap; } diff --git a/contrib/llvm-project/clang/lib/AST/ASTStructuralEquivalence.cpp b/contrib/llvm-project/clang/lib/AST/ASTStructuralEquivalence.cpp index e85feb779190..7fd24e2aa9ad 100644 --- a/contrib/llvm-project/clang/lib/AST/ASTStructuralEquivalence.cpp +++ b/contrib/llvm-project/clang/lib/AST/ASTStructuralEquivalence.cpp @@ -1347,6 +1347,42 @@ IsStructurallyEquivalentLambdas(StructuralEquivalenceContext &Context, return true; } +/// Determine if context of a class is equivalent. +static bool IsRecordContextStructurallyEquivalent(RecordDecl *D1, + RecordDecl *D2) { + // The context should be completely equal, including anonymous and inline + // namespaces. + // We compare objects as part of full translation units, not subtrees of + // translation units. + DeclContext *DC1 = D1->getDeclContext()->getNonTransparentContext(); + DeclContext *DC2 = D2->getDeclContext()->getNonTransparentContext(); + while (true) { + // Special case: We allow a struct defined in a function to be equivalent + // with a similar struct defined outside of a function. + if ((DC1->isFunctionOrMethod() && DC2->isTranslationUnit()) || + (DC2->isFunctionOrMethod() && DC1->isTranslationUnit())) + return true; + + if (DC1->getDeclKind() != DC2->getDeclKind()) + return false; + if (DC1->isTranslationUnit()) + break; + if (DC1->isInlineNamespace() != DC2->isInlineNamespace()) + return false; + if (const auto *ND1 = dyn_cast(DC1)) { + const auto *ND2 = cast(DC2); + if (!DC1->isInlineNamespace() && + !IsStructurallyEquivalent(ND1->getIdentifier(), ND2->getIdentifier())) + return false; + } + + DC1 = DC1->getParent()->getNonTransparentContext(); + DC2 = DC2->getParent()->getNonTransparentContext(); + } + + return true; +} + /// Determine structural equivalence of two records. static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, RecordDecl *D1, RecordDecl *D2) { @@ -1386,6 +1422,12 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, } } + // If the records occur in different context (namespace), these should be + // different. This is specially important if the definition of one or both + // records is missing. + if (!IsRecordContextStructurallyEquivalent(D1, D2)) + return false; + // If both declarations are class template specializations, we know // the ODR applies, so check the template and template arguments. const auto *Spec1 = dyn_cast(D1); diff --git a/contrib/llvm-project/clang/lib/AST/Decl.cpp b/contrib/llvm-project/clang/lib/AST/Decl.cpp index 53a04ad0df4e..8291e721553f 100644 --- a/contrib/llvm-project/clang/lib/AST/Decl.cpp +++ b/contrib/llvm-project/clang/lib/AST/Decl.cpp @@ -3256,6 +3256,8 @@ MultiVersionKind FunctionDecl::getMultiVersionKind() const { return MultiVersionKind::CPUDispatch; if (hasAttr()) return MultiVersionKind::CPUSpecific; + if (hasAttr()) + return MultiVersionKind::TargetClones; return MultiVersionKind::None; } @@ -3271,6 +3273,10 @@ bool FunctionDecl::isTargetMultiVersion() const { return isMultiVersion() && hasAttr(); } +bool FunctionDecl::isTargetClonesMultiVersion() const { + return isMultiVersion() && hasAttr(); +} + void FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) { redeclarable_base::setPreviousDecl(PrevDecl); diff --git a/contrib/llvm-project/clang/lib/AST/DeclBase.cpp b/contrib/llvm-project/clang/lib/AST/DeclBase.cpp index 4044404f74ef..064012ba865c 100644 --- a/contrib/llvm-project/clang/lib/AST/DeclBase.cpp +++ b/contrib/llvm-project/clang/lib/AST/DeclBase.cpp @@ -964,7 +964,7 @@ SourceLocation Decl::getBodyRBrace() const { return {}; } -bool Decl::AccessDeclContextSanity() const { +bool Decl::AccessDeclContextCheck() const { #ifndef NDEBUG // Suppress this check if any of the following hold: // 1. this is the translation unit (and thus has no parent) @@ -1212,7 +1212,7 @@ bool DeclContext::Encloses(const DeclContext *DC) const { return getPrimaryContext()->Encloses(DC); for (; DC; DC = DC->getParent()) - if (DC->getPrimaryContext() == this) + if (!isa(DC) && DC->getPrimaryContext() == this) return true; return false; } diff --git a/contrib/llvm-project/clang/lib/AST/Expr.cpp b/contrib/llvm-project/clang/lib/AST/Expr.cpp index 7bd3dce43f4d..d3cb2ff3734c 100644 --- a/contrib/llvm-project/clang/lib/AST/Expr.cpp +++ b/contrib/llvm-project/clang/lib/AST/Expr.cpp @@ -4681,6 +4681,7 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) { return 2; case AO__opencl_atomic_load: + case AO__hip_atomic_load: case AO__c11_atomic_store: case AO__c11_atomic_exchange: case AO__atomic_load: @@ -4713,7 +4714,15 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) { case AO__atomic_fetch_max: return 3; + case AO__hip_atomic_exchange: + case AO__hip_atomic_fetch_add: + case AO__hip_atomic_fetch_and: + case AO__hip_atomic_fetch_or: + case AO__hip_atomic_fetch_xor: + case AO__hip_atomic_fetch_min: + case AO__hip_atomic_fetch_max: case AO__opencl_atomic_store: + case AO__hip_atomic_store: case AO__opencl_atomic_exchange: case AO__opencl_atomic_fetch_add: case AO__opencl_atomic_fetch_sub: @@ -4728,9 +4737,10 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) { case AO__c11_atomic_compare_exchange_strong: case AO__c11_atomic_compare_exchange_weak: return 5; - + case AO__hip_atomic_compare_exchange_strong: case AO__opencl_atomic_compare_exchange_strong: case AO__opencl_atomic_compare_exchange_weak: + case AO__hip_atomic_compare_exchange_weak: case AO__atomic_compare_exchange: case AO__atomic_compare_exchange_n: return 6; diff --git a/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp b/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp index 6cc632060e7b..2e458e2c659c 100644 --- a/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp +++ b/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp @@ -7486,7 +7486,7 @@ class ExprEvaluatorBase const Expr *Source = E->getSourceExpr(); if (!Source) return Error(E); - if (Source == E) { // sanity checking. + if (Source == E) { assert(0 && "OpaqueValueExpr recursively refers to itself"); return Error(E); } diff --git a/contrib/llvm-project/clang/lib/AST/MicrosoftMangle.cpp b/contrib/llvm-project/clang/lib/AST/MicrosoftMangle.cpp index 163d4e95386e..79a448a2435c 100644 --- a/contrib/llvm-project/clang/lib/AST/MicrosoftMangle.cpp +++ b/contrib/llvm-project/clang/lib/AST/MicrosoftMangle.cpp @@ -21,6 +21,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/GlobalDecl.h" #include "clang/AST/Mangle.h" #include "clang/AST/VTableBuilder.h" #include "clang/Basic/ABI.h" @@ -39,6 +40,18 @@ using namespace clang; namespace { +// Get GlobalDecl of DeclContext of local entities. +static GlobalDecl getGlobalDeclAsDeclContext(const DeclContext *DC) { + GlobalDecl GD; + if (auto *CD = dyn_cast(DC)) + GD = GlobalDecl(CD, Ctor_Complete); + else if (auto *DD = dyn_cast(DC)) + GD = GlobalDecl(DD, Dtor_Complete); + else + GD = GlobalDecl(cast(DC)); + return GD; +} + struct msvc_hashing_ostream : public llvm::raw_svector_ostream { raw_ostream &OS; llvm::SmallString<64> Buffer; @@ -345,9 +358,9 @@ class MicrosoftCXXNameMangler { raw_ostream &getStream() const { return Out; } - void mangle(const NamedDecl *D, StringRef Prefix = "?"); - void mangleName(const NamedDecl *ND); - void mangleFunctionEncoding(const FunctionDecl *FD, bool ShouldMangle); + void mangle(GlobalDecl GD, StringRef Prefix = "?"); + void mangleName(GlobalDecl GD); + void mangleFunctionEncoding(GlobalDecl GD, bool ShouldMangle); void mangleVariableEncoding(const VarDecl *VD); void mangleMemberDataPointer(const CXXRecordDecl *RD, const ValueDecl *VD, StringRef Prefix = "$"); @@ -370,7 +383,7 @@ class MicrosoftCXXNameMangler { const FunctionDecl *D = nullptr, bool ForceThisQuals = false, bool MangleExceptionSpec = true); - void mangleNestedName(const NamedDecl *ND); + void mangleNestedName(GlobalDecl GD); private: bool isStructorDecl(const NamedDecl *ND) const { @@ -384,10 +397,10 @@ class MicrosoftCXXNameMangler { AddrSpace == LangAS::ptr32_uptr)); } - void mangleUnqualifiedName(const NamedDecl *ND) { - mangleUnqualifiedName(ND, ND->getDeclName()); + void mangleUnqualifiedName(GlobalDecl GD) { + mangleUnqualifiedName(GD, cast(GD.getDecl())->getDeclName()); } - void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name); + void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name); void mangleSourceName(StringRef Name); void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc); void mangleCXXDtorType(CXXDtorType T); @@ -396,9 +409,9 @@ class MicrosoftCXXNameMangler { void manglePointerCVQualifiers(Qualifiers Quals); void manglePointerExtQualifiers(Qualifiers Quals, QualType PointeeType); - void mangleUnscopedTemplateName(const TemplateDecl *ND); + void mangleUnscopedTemplateName(GlobalDecl GD); void - mangleTemplateInstantiationName(const TemplateDecl *TD, + mangleTemplateInstantiationName(GlobalDecl GD, const TemplateArgumentList &TemplateArgs); void mangleObjCMethodName(const ObjCMethodDecl *MD); @@ -533,7 +546,8 @@ MicrosoftMangleContextImpl::shouldMangleStringLiteral(const StringLiteral *SL) { return true; } -void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) { +void MicrosoftCXXNameMangler::mangle(GlobalDecl GD, StringRef Prefix) { + const NamedDecl *D = cast(GD.getDecl()); // MSVC doesn't mangle C++ names the same way it mangles extern "C" names. // Therefore it's really important that we don't decorate the // name with leading underscores or leading/trailing at signs. So, by @@ -542,9 +556,9 @@ void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) { // ::= ? Out << Prefix; - mangleName(D); + mangleName(GD); if (const FunctionDecl *FD = dyn_cast(D)) - mangleFunctionEncoding(FD, Context.shouldMangleDeclName(FD)); + mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD)); else if (const VarDecl *VD = dyn_cast(D)) mangleVariableEncoding(VD); else if (isa(D)) @@ -558,8 +572,9 @@ void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) { llvm_unreachable("Tried to mangle unexpected NamedDecl!"); } -void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD, +void MicrosoftCXXNameMangler::mangleFunctionEncoding(GlobalDecl GD, bool ShouldMangle) { + const FunctionDecl *FD = cast(GD.getDecl()); // ::= // Since MSVC operates on the type as written and not the canonical type, it @@ -770,13 +785,13 @@ void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk( mangleCallingConvention(MD->getType()->castAs()); } -void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) { +void MicrosoftCXXNameMangler::mangleName(GlobalDecl GD) { // ::= {[]+ | []}? @ // Always start with the unqualified name. - mangleUnqualifiedName(ND); + mangleUnqualifiedName(GD); - mangleNestedName(ND); + mangleNestedName(GD); // Terminate the whole name with an '@'. Out << '@'; @@ -844,13 +859,14 @@ void MicrosoftCXXNameMangler::mangleBits(llvm::APInt Value) { } } -static const TemplateDecl * -isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) { +static GlobalDecl isTemplate(GlobalDecl GD, + const TemplateArgumentList *&TemplateArgs) { + const NamedDecl *ND = cast(GD.getDecl()); // Check if we have a function template. if (const FunctionDecl *FD = dyn_cast(ND)) { if (const TemplateDecl *TD = FD->getPrimaryTemplate()) { TemplateArgs = FD->getTemplateSpecializationArgs(); - return TD; + return GD.getWithDecl(TD); } } @@ -858,21 +874,22 @@ isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) { if (const ClassTemplateSpecializationDecl *Spec = dyn_cast(ND)) { TemplateArgs = &Spec->getTemplateArgs(); - return Spec->getSpecializedTemplate(); + return GD.getWithDecl(Spec->getSpecializedTemplate()); } // Check if we have a variable template. if (const VarTemplateSpecializationDecl *Spec = dyn_cast(ND)) { TemplateArgs = &Spec->getTemplateArgs(); - return Spec->getSpecializedTemplate(); + return GD.getWithDecl(Spec->getSpecializedTemplate()); } - return nullptr; + return GlobalDecl(); } -void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, +void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name) { + const NamedDecl *ND = cast(GD.getDecl()); // ::= // ::= // ::= @@ -880,11 +897,11 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; - if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { + if (GlobalDecl TD = isTemplate(GD, TemplateArgs)) { // Function templates aren't considered for name back referencing. This // makes sense since function templates aren't likely to occur multiple // times in a symbol. - if (isa(TD)) { + if (isa(TD.getDecl())) { mangleTemplateInstantiationName(TD, *TemplateArgs); Out << '@'; return; @@ -945,7 +962,19 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, switch (Name.getNameKind()) { case DeclarationName::Identifier: { if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) { - mangleSourceName(II->getName()); + bool IsDeviceStub = + ND && + ((isa(ND) && ND->hasAttr()) || + (isa(ND) && + cast(ND) + ->getTemplatedDecl() + ->hasAttr())) && + GD.getKernelReferenceKind() == KernelReferenceKind::Stub; + if (IsDeviceStub) + mangleSourceName( + (llvm::Twine("__device_stub__") + II->getName()).str()); + else + mangleSourceName(II->getName()); break; } @@ -1146,7 +1175,8 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, // ::= [] // ::= [] -void MicrosoftCXXNameMangler::mangleNestedName(const NamedDecl *ND) { +void MicrosoftCXXNameMangler::mangleNestedName(GlobalDecl GD) { + const NamedDecl *ND = cast(GD.getDecl()); const DeclContext *DC = getEffectiveDeclContext(ND); while (!DC->isTranslationUnit()) { if (isa(ND) || isa(ND)) { @@ -1229,7 +1259,7 @@ void MicrosoftCXXNameMangler::mangleNestedName(const NamedDecl *ND) { } else if (isa(DC)) { ND = cast(DC); if (const FunctionDecl *FD = dyn_cast(ND)) { - mangle(FD, "?"); + mangle(getGlobalDeclAsDeclContext(FD), "?"); break; } else { mangleUnqualifiedName(ND); @@ -1418,7 +1448,7 @@ void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) { } void MicrosoftCXXNameMangler::mangleTemplateInstantiationName( - const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) { + GlobalDecl GD, const TemplateArgumentList &TemplateArgs) { // ::= // ::= // Always start with the unqualified name. @@ -1433,8 +1463,8 @@ void MicrosoftCXXNameMangler::mangleTemplateInstantiationName( TemplateArgBackReferences.swap(OuterTemplateArgsContext); PassObjectSizeArgs.swap(OuterPassObjectSizeArgs); - mangleUnscopedTemplateName(TD); - mangleTemplateArgs(TD, TemplateArgs); + mangleUnscopedTemplateName(GD); + mangleTemplateArgs(cast(GD.getDecl()), TemplateArgs); // Restore the previous back reference contexts. NameBackReferences.swap(OuterTemplateContext); @@ -1443,11 +1473,10 @@ void MicrosoftCXXNameMangler::mangleTemplateInstantiationName( PassObjectSizeArgs.swap(OuterPassObjectSizeArgs); } -void -MicrosoftCXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *TD) { +void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(GlobalDecl GD) { // ::= ?$ Out << "?$"; - mangleUnqualifiedName(TD); + mangleUnqualifiedName(GD); } void MicrosoftCXXNameMangler::mangleIntegerLiteral( @@ -3323,17 +3352,17 @@ void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD, if (auto *CD = dyn_cast(D)) { auto Type = GD.getCtorType(); MicrosoftCXXNameMangler mangler(*this, MHO, CD, Type); - return mangler.mangle(D); + return mangler.mangle(GD); } if (auto *DD = dyn_cast(D)) { auto Type = GD.getDtorType(); MicrosoftCXXNameMangler mangler(*this, MHO, DD, Type); - return mangler.mangle(D); + return mangler.mangle(GD); } MicrosoftCXXNameMangler Mangler(*this, MHO); - return Mangler.mangle(D); + return Mangler.mangle(GD); } void MicrosoftCXXNameMangler::mangleType(const ExtIntType *T, Qualifiers, diff --git a/contrib/llvm-project/clang/lib/AST/StmtPrinter.cpp b/contrib/llvm-project/clang/lib/AST/StmtPrinter.cpp index fc267d7006a1..b65a38d1e566 100644 --- a/contrib/llvm-project/clang/lib/AST/StmtPrinter.cpp +++ b/contrib/llvm-project/clang/lib/AST/StmtPrinter.cpp @@ -1691,7 +1691,8 @@ void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) { PrintExpr(Node->getPtr()); if (Node->getOp() != AtomicExpr::AO__c11_atomic_load && Node->getOp() != AtomicExpr::AO__atomic_load_n && - Node->getOp() != AtomicExpr::AO__opencl_atomic_load) { + Node->getOp() != AtomicExpr::AO__opencl_atomic_load && + Node->getOp() != AtomicExpr::AO__hip_atomic_load) { OS << ", "; PrintExpr(Node->getVal1()); } diff --git a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp new file mode 100644 index 000000000000..bb7eb9971068 --- /dev/null +++ b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -0,0 +1,35 @@ +//===- TypeErasedDataflowAnalysis.cpp -------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines type-erased base types and functions for building dataflow +// analyses that run over Control-Flow Graphs (CFGs). +// +//===----------------------------------------------------------------------===// + +#include + +#include "clang/Analysis/CFG.h" +#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" +#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h" +#include "llvm/ADT/Optional.h" + +using namespace clang; +using namespace dataflow; + +std::vector> +runTypeErasedDataflowAnalysis(const CFG &Cfg, + TypeErasedDataflowAnalysis &Analysis, + const Environment &InitEnv) { + // FIXME: Consider enforcing that `Cfg` meets the requirements that + // are specified in the header. This could be done by remembering + // what options were used to build `Cfg` and asserting on them here. + + // FIXME: Implement work list-based algorithm to compute the fixed + // point of `Analysis::transform` for every basic block in `Cfg`. + return {}; +} diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp index f75b8ffcb53d..4d403ae1809d 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp @@ -140,8 +140,8 @@ bool AArch64TargetInfo::setABI(const std::string &Name) { bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, BranchProtectionInfo &BPI, StringRef &Err) const { - llvm::AArch64::ParsedBranchProtection PBP; - if (!llvm::AArch64::parseBranchProtection(Spec, PBP, Err)) + llvm::ARM::ParsedBranchProtection PBP; + if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err)) return false; BPI.SignReturnAddr = diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp index fc6b01c87fd2..f330780300f2 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp @@ -367,6 +367,28 @@ bool ARMTargetInfo::setABI(const std::string &Name) { return false; } +bool ARMTargetInfo::validateBranchProtection(StringRef Spec, + BranchProtectionInfo &BPI, + StringRef &Err) const { + llvm::ARM::ParsedBranchProtection PBP; + if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err)) + return false; + + BPI.SignReturnAddr = + llvm::StringSwitch(PBP.Scope) + .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf) + .Case("all", LangOptions::SignReturnAddressScopeKind::All) + .Default(LangOptions::SignReturnAddressScopeKind::None); + + // Don't care for the sign key, beyond issuing a warning. + if (PBP.Key == "b_key") + Err = "b-key"; + BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey; + + BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement; + return true; +} + // FIXME: This should be based on Arch attributes, not CPU names. bool ARMTargetInfo::initFeatureMap( llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, @@ -874,6 +896,16 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1"); } + if (Opts.BranchTargetEnforcement) + Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1"); + + if (Opts.hasSignReturnAddress()) { + unsigned Value = Opts.isSignReturnAddressWithAKey() ? 1 : 2; + if (Opts.isSignReturnAddressScopeAll()) + Value |= 1 << 2; + Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value)); + } + switch (ArchKind) { default: break; diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h index d54a049042d6..7d0011d134ea 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h @@ -123,6 +123,9 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo { StringRef getABI() const override; bool setABI(const std::string &Name) override; + bool validateBranchProtection(StringRef, BranchProtectionInfo &, + StringRef &) const override; + // FIXME: This should be based on Arch attributes, not CPU names. bool initFeatureMap(llvm::StringMap &Features, DiagnosticsEngine &Diags, diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp index 7cd4a5190120..53748bf067cd 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp @@ -181,8 +181,10 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) { Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1)); if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) { - if (Opts.CPlusPlus20) - Builder.defineMacro("_MSVC_LANG", "201705L"); + if (Opts.CPlusPlus2b) + Builder.defineMacro("_MSVC_LANG", "202004L"); + else if (Opts.CPlusPlus20) + Builder.defineMacro("_MSVC_LANG", "202002L"); else if (Opts.CPlusPlus17) Builder.defineMacro("_MSVC_LANG", "201703L"); else if (Opts.CPlusPlus14) @@ -201,6 +203,14 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) { } Builder.defineMacro("_INTEGRAL_MAX_BITS", "64"); + + // Starting with VS 2022 17.1, MSVC predefines the below macro to inform + // users of the execution character set defined at compile time. + // The value given is the Windows Code Page Identifier: + // https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers + // + // Clang currently only supports UTF-8, so we'll use 65001 + Builder.defineMacro("_MSVC_EXECUTION_CHARACTER_SET", "65001"); } void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts, diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h b/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h index 704b1843dfed..8cf18b6c20f1 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h +++ b/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h @@ -56,9 +56,14 @@ static const unsigned SPIRDefIsGenMap[] = { 0, // opencl_generic 0, // opencl_global_device 0, // opencl_global_host - 0, // cuda_device - 0, // cuda_constant - 0, // cuda_shared + // cuda_* address space mapping is intended for HIPSPV (HIP to SPIR-V + // translation). This mapping is enabled when the language mode is HIP. + 1, // cuda_device + // cuda_constant pointer can be casted to default/"flat" pointer, but in + // SPIR-V casts between constant and generic pointers are not allowed. For + // this reason cuda_constant is mapped to SPIR-V CrossWorkgroup. + 1, // cuda_constant + 3, // cuda_shared 1, // sycl_global 5, // sycl_global_device 6, // sycl_global_host @@ -74,6 +79,8 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo { protected: BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { + assert((Triple.isSPIR() || Triple.isSPIRV()) && + "Invalid architecture for SPIR or SPIR-V."); assert(getTriple().getOS() == llvm::Triple::UnknownOS && "SPIR(-V) target must use unknown OS"); assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && @@ -137,11 +144,16 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo { // FIXME: SYCL specification considers unannotated pointers and references // to be pointing to the generic address space. See section 5.9.3 of // SYCL 2020 specification. - // Currently, there is no way of representing SYCL's default address space - // language semantic along with the semantics of embedded C's default - // address space in the same address space map. Hence the map needs to be - // reset to allow mapping to the desired value of 'Default' entry for SYCL. - setAddressSpaceMap(/*DefaultIsGeneric=*/Opts.SYCLIsDevice); + // Currently, there is no way of representing SYCL's and HIP's default + // address space language semantic along with the semantics of embedded C's + // default address space in the same address space map. Hence the map needs + // to be reset to allow mapping to the desired value of 'Default' entry for + // SYCL and HIP. + setAddressSpaceMap( + /*DefaultIsGeneric=*/Opts.SYCLIsDevice || + // The address mapping from HIP language for device code is only defined + // for SPIR-V. + (getTriple().isSPIRV() && Opts.HIP && Opts.CUDAIsDevice)); } void setSupportedOpenCLOpts() override { @@ -159,6 +171,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo { public: SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : BaseSPIRTargetInfo(Triple, Opts) { + assert(Triple.isSPIR() && "Invalid architecture for SPIR."); assert(getTriple().getOS() == llvm::Triple::UnknownOS && "SPIR target must use unknown OS"); assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && @@ -177,6 +190,8 @@ class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo { public: SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : SPIRTargetInfo(Triple, Opts) { + assert(Triple.getArch() == llvm::Triple::spir && + "Invalid architecture for 32-bit SPIR."); PointerWidth = PointerAlign = 32; SizeType = TargetInfo::UnsignedInt; PtrDiffType = IntPtrType = TargetInfo::SignedInt; @@ -192,6 +207,8 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo { public: SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : SPIRTargetInfo(Triple, Opts) { + assert(Triple.getArch() == llvm::Triple::spir64 && + "Invalid architecture for 64-bit SPIR."); PointerWidth = PointerAlign = 64; SizeType = TargetInfo::UnsignedLong; PtrDiffType = IntPtrType = TargetInfo::SignedLong; @@ -207,6 +224,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRTargetInfo { public: SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : BaseSPIRTargetInfo(Triple, Opts) { + assert(Triple.isSPIRV() && "Invalid architecture for SPIR-V."); assert(getTriple().getOS() == llvm::Triple::UnknownOS && "SPIR-V target must use unknown OS"); assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && @@ -225,6 +243,8 @@ class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public SPIRVTargetInfo { public: SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : SPIRVTargetInfo(Triple, Opts) { + assert(Triple.getArch() == llvm::Triple::spirv32 && + "Invalid architecture for 32-bit SPIR-V."); PointerWidth = PointerAlign = 32; SizeType = TargetInfo::UnsignedInt; PtrDiffType = IntPtrType = TargetInfo::SignedInt; @@ -240,6 +260,8 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public SPIRVTargetInfo { public: SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : SPIRVTargetInfo(Triple, Opts) { + assert(Triple.getArch() == llvm::Triple::spirv64 && + "Invalid architecture for 64-bit SPIR-V."); PointerWidth = PointerAlign = 64; SizeType = TargetInfo::UnsignedLong; PtrDiffType = IntPtrType = TargetInfo::SignedLong; diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp index 5e3686893719..5c4bd364b06a 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp @@ -239,9 +239,9 @@ bool X86TargetInfo::handleTargetFeatures(std::vector &Features, HasAVX512ER = true; } else if (Feature == "+avx512fp16") { HasAVX512FP16 = true; + HasFloat16 = true; } else if (Feature == "+avx512pf") { HasAVX512PF = true; - HasLegalHalfType = true; } else if (Feature == "+avx512dq") { HasAVX512DQ = true; } else if (Feature == "+avx512bitalg") { @@ -369,8 +369,6 @@ bool X86TargetInfo::handleTargetFeatures(std::vector &Features, .Default(NoXOP); XOPLevel = std::max(XOPLevel, XLevel); } - // Turn on _float16 for x86 (feature sse2) - HasFloat16 = SSELevel >= SSE2; // LLVM doesn't have a separate switch for fpmath, so only accept it if it // matches the selected sse level. @@ -384,12 +382,10 @@ bool X86TargetInfo::handleTargetFeatures(std::vector &Features, SimdDefaultAlign = hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128; - if (!HasX87) { - if (LongDoubleFormat == &llvm::APFloat::x87DoubleExtended()) - HasLongDouble = false; - if (getTriple().getArch() == llvm::Triple::x86) - HasFPReturn = false; - } + // FIXME: We should allow long double type on 32-bits to match with GCC. + // This requires backend to be able to lower f80 without x87 first. + if (!HasX87 && LongDoubleFormat == &llvm::APFloat::x87DoubleExtended()) + HasLongDouble = false; return true; } diff --git a/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp b/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp index 648c7b3df8ed..510f3911939c 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp @@ -1034,8 +1034,9 @@ void EmitAssemblyHelper::EmitAssemblyWithLegacyPassManager( if (!ThinLinkOS) return; } - TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", - CodeGenOpts.EnableSplitLTOUnit); + if (!TheModule->getModuleFlag("EnableSplitLTOUnit")) + TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", + CodeGenOpts.EnableSplitLTOUnit); PerModulePasses.add(createWriteThinLTOBitcodePass( *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr)); } else { @@ -1049,8 +1050,9 @@ void EmitAssemblyHelper::EmitAssemblyWithLegacyPassManager( if (EmitLTOSummary) { if (!TheModule->getModuleFlag("ThinLTO")) TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); - TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", - uint32_t(1)); + if (!TheModule->getModuleFlag("EnableSplitLTOUnit")) + TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", + uint32_t(1)); } PerModulePasses.add(createBitcodeWriterPass( @@ -1451,8 +1453,9 @@ void EmitAssemblyHelper::RunOptimizationPipeline( if (!ThinLinkOS) return; } - TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", - CodeGenOpts.EnableSplitLTOUnit); + if (!TheModule->getModuleFlag("EnableSplitLTOUnit")) + TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", + CodeGenOpts.EnableSplitLTOUnit); MPM.addPass(ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr)); } else { @@ -1465,8 +1468,9 @@ void EmitAssemblyHelper::RunOptimizationPipeline( if (EmitLTOSummary) { if (!TheModule->getModuleFlag("ThinLTO")) TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); - TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", - uint32_t(1)); + if (!TheModule->getModuleFlag("EnableSplitLTOUnit")) + TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", + uint32_t(1)); } MPM.addPass( BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists, EmitLTOSummary)); diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGAtomic.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGAtomic.cpp index 326ca8d50533..b68e6328acdf 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGAtomic.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CGAtomic.cpp @@ -524,12 +524,14 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, llvm_unreachable("Already handled!"); case AtomicExpr::AO__c11_atomic_compare_exchange_strong: + case AtomicExpr::AO__hip_atomic_compare_exchange_strong: case AtomicExpr::AO__opencl_atomic_compare_exchange_strong: emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2, FailureOrder, Size, Order, Scope); return; case AtomicExpr::AO__c11_atomic_compare_exchange_weak: case AtomicExpr::AO__opencl_atomic_compare_exchange_weak: + case AtomicExpr::AO__hip_atomic_compare_exchange_weak: emitAtomicCmpXchgFailureSet(CGF, E, true, Dest, Ptr, Val1, Val2, FailureOrder, Size, Order, Scope); return; @@ -565,6 +567,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, } case AtomicExpr::AO__c11_atomic_load: case AtomicExpr::AO__opencl_atomic_load: + case AtomicExpr::AO__hip_atomic_load: case AtomicExpr::AO__atomic_load_n: case AtomicExpr::AO__atomic_load: { llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr); @@ -576,6 +579,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, case AtomicExpr::AO__c11_atomic_store: case AtomicExpr::AO__opencl_atomic_store: + case AtomicExpr::AO__hip_atomic_store: case AtomicExpr::AO__atomic_store: case AtomicExpr::AO__atomic_store_n: { llvm::Value *LoadVal1 = CGF.Builder.CreateLoad(Val1); @@ -586,6 +590,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, } case AtomicExpr::AO__c11_atomic_exchange: + case AtomicExpr::AO__hip_atomic_exchange: case AtomicExpr::AO__opencl_atomic_exchange: case AtomicExpr::AO__atomic_exchange_n: case AtomicExpr::AO__atomic_exchange: @@ -597,6 +602,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, : llvm::Instruction::Add; LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_add: + case AtomicExpr::AO__hip_atomic_fetch_add: case AtomicExpr::AO__opencl_atomic_fetch_add: case AtomicExpr::AO__atomic_fetch_add: Op = E->getValueType()->isFloatingType() ? llvm::AtomicRMWInst::FAdd @@ -618,6 +624,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, PostOpMinMax = true; LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_min: + case AtomicExpr::AO__hip_atomic_fetch_min: case AtomicExpr::AO__opencl_atomic_fetch_min: case AtomicExpr::AO__atomic_fetch_min: Op = E->getValueType()->isSignedIntegerType() ? llvm::AtomicRMWInst::Min @@ -628,6 +635,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, PostOpMinMax = true; LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_max: + case AtomicExpr::AO__hip_atomic_fetch_max: case AtomicExpr::AO__opencl_atomic_fetch_max: case AtomicExpr::AO__atomic_fetch_max: Op = E->getValueType()->isSignedIntegerType() ? llvm::AtomicRMWInst::Max @@ -638,6 +646,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, PostOp = llvm::Instruction::And; LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_and: + case AtomicExpr::AO__hip_atomic_fetch_and: case AtomicExpr::AO__opencl_atomic_fetch_and: case AtomicExpr::AO__atomic_fetch_and: Op = llvm::AtomicRMWInst::And; @@ -647,6 +656,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, PostOp = llvm::Instruction::Or; LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_or: + case AtomicExpr::AO__hip_atomic_fetch_or: case AtomicExpr::AO__opencl_atomic_fetch_or: case AtomicExpr::AO__atomic_fetch_or: Op = llvm::AtomicRMWInst::Or; @@ -656,6 +666,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, PostOp = llvm::Instruction::Xor; LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_xor: + case AtomicExpr::AO__hip_atomic_fetch_xor: case AtomicExpr::AO__opencl_atomic_fetch_xor: case AtomicExpr::AO__atomic_fetch_xor: Op = llvm::AtomicRMWInst::Xor; @@ -838,6 +849,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { case AtomicExpr::AO__c11_atomic_load: case AtomicExpr::AO__opencl_atomic_load: + case AtomicExpr::AO__hip_atomic_load: case AtomicExpr::AO__atomic_load_n: break; @@ -857,7 +869,9 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { case AtomicExpr::AO__c11_atomic_compare_exchange_strong: case AtomicExpr::AO__c11_atomic_compare_exchange_weak: case AtomicExpr::AO__opencl_atomic_compare_exchange_strong: + case AtomicExpr::AO__hip_atomic_compare_exchange_strong: case AtomicExpr::AO__opencl_atomic_compare_exchange_weak: + case AtomicExpr::AO__hip_atomic_compare_exchange_weak: case AtomicExpr::AO__atomic_compare_exchange_n: case AtomicExpr::AO__atomic_compare_exchange: Val1 = EmitPointerWithAlignment(E->getVal1()); @@ -873,6 +887,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { case AtomicExpr::AO__c11_atomic_fetch_add: case AtomicExpr::AO__c11_atomic_fetch_sub: + case AtomicExpr::AO__hip_atomic_fetch_add: case AtomicExpr::AO__opencl_atomic_fetch_add: case AtomicExpr::AO__opencl_atomic_fetch_sub: if (MemTy->isPointerType()) { @@ -901,7 +916,9 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { case AtomicExpr::AO__c11_atomic_store: case AtomicExpr::AO__c11_atomic_exchange: case AtomicExpr::AO__opencl_atomic_store: + case AtomicExpr::AO__hip_atomic_store: case AtomicExpr::AO__opencl_atomic_exchange: + case AtomicExpr::AO__hip_atomic_exchange: case AtomicExpr::AO__atomic_store_n: case AtomicExpr::AO__atomic_exchange_n: case AtomicExpr::AO__c11_atomic_fetch_and: @@ -916,8 +933,11 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { case AtomicExpr::AO__opencl_atomic_fetch_min: case AtomicExpr::AO__opencl_atomic_fetch_max: case AtomicExpr::AO__atomic_fetch_and: + case AtomicExpr::AO__hip_atomic_fetch_and: case AtomicExpr::AO__atomic_fetch_or: + case AtomicExpr::AO__hip_atomic_fetch_or: case AtomicExpr::AO__atomic_fetch_xor: + case AtomicExpr::AO__hip_atomic_fetch_xor: case AtomicExpr::AO__atomic_fetch_nand: case AtomicExpr::AO__atomic_and_fetch: case AtomicExpr::AO__atomic_or_fetch: @@ -926,7 +946,9 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { case AtomicExpr::AO__atomic_max_fetch: case AtomicExpr::AO__atomic_min_fetch: case AtomicExpr::AO__atomic_fetch_max: + case AtomicExpr::AO__hip_atomic_fetch_max: case AtomicExpr::AO__atomic_fetch_min: + case AtomicExpr::AO__hip_atomic_fetch_min: Val1 = EmitValToTemp(*this, E->getVal1()); break; } @@ -968,11 +990,14 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { case AtomicExpr::AO__c11_atomic_fetch_add: case AtomicExpr::AO__opencl_atomic_fetch_add: case AtomicExpr::AO__atomic_fetch_add: + case AtomicExpr::AO__hip_atomic_fetch_add: case AtomicExpr::AO__c11_atomic_fetch_and: case AtomicExpr::AO__opencl_atomic_fetch_and: + case AtomicExpr::AO__hip_atomic_fetch_and: case AtomicExpr::AO__atomic_fetch_and: case AtomicExpr::AO__c11_atomic_fetch_or: case AtomicExpr::AO__opencl_atomic_fetch_or: + case AtomicExpr::AO__hip_atomic_fetch_or: case AtomicExpr::AO__atomic_fetch_or: case AtomicExpr::AO__c11_atomic_fetch_nand: case AtomicExpr::AO__atomic_fetch_nand: @@ -984,6 +1009,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { case AtomicExpr::AO__opencl_atomic_fetch_min: case AtomicExpr::AO__opencl_atomic_fetch_max: case AtomicExpr::AO__atomic_fetch_xor: + case AtomicExpr::AO__hip_atomic_fetch_xor: case AtomicExpr::AO__c11_atomic_fetch_max: case AtomicExpr::AO__c11_atomic_fetch_min: case AtomicExpr::AO__atomic_add_fetch: @@ -993,7 +1019,9 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { case AtomicExpr::AO__atomic_sub_fetch: case AtomicExpr::AO__atomic_xor_fetch: case AtomicExpr::AO__atomic_fetch_max: + case AtomicExpr::AO__hip_atomic_fetch_max: case AtomicExpr::AO__atomic_fetch_min: + case AtomicExpr::AO__hip_atomic_fetch_min: case AtomicExpr::AO__atomic_max_fetch: case AtomicExpr::AO__atomic_min_fetch: // For these, only library calls for certain sizes exist. @@ -1014,10 +1042,15 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { case AtomicExpr::AO__c11_atomic_exchange: case AtomicExpr::AO__c11_atomic_compare_exchange_weak: case AtomicExpr::AO__c11_atomic_compare_exchange_strong: + case AtomicExpr::AO__hip_atomic_compare_exchange_strong: case AtomicExpr::AO__opencl_atomic_load: + case AtomicExpr::AO__hip_atomic_load: case AtomicExpr::AO__opencl_atomic_store: + case AtomicExpr::AO__hip_atomic_store: case AtomicExpr::AO__opencl_atomic_exchange: + case AtomicExpr::AO__hip_atomic_exchange: case AtomicExpr::AO__opencl_atomic_compare_exchange_weak: + case AtomicExpr::AO__hip_atomic_compare_exchange_weak: case AtomicExpr::AO__opencl_atomic_compare_exchange_strong: case AtomicExpr::AO__atomic_load_n: case AtomicExpr::AO__atomic_store_n: @@ -1079,7 +1112,9 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { case AtomicExpr::AO__c11_atomic_compare_exchange_weak: case AtomicExpr::AO__c11_atomic_compare_exchange_strong: case AtomicExpr::AO__opencl_atomic_compare_exchange_weak: + case AtomicExpr::AO__hip_atomic_compare_exchange_weak: case AtomicExpr::AO__opencl_atomic_compare_exchange_strong: + case AtomicExpr::AO__hip_atomic_compare_exchange_strong: case AtomicExpr::AO__atomic_compare_exchange: case AtomicExpr::AO__atomic_compare_exchange_n: LibCallName = "__atomic_compare_exchange"; @@ -1101,6 +1136,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { case AtomicExpr::AO__opencl_atomic_exchange: case AtomicExpr::AO__atomic_exchange_n: case AtomicExpr::AO__atomic_exchange: + case AtomicExpr::AO__hip_atomic_exchange: LibCallName = "__atomic_exchange"; AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), MemTy, E->getExprLoc(), TInfo.Width); @@ -1109,6 +1145,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { // void __atomic_store_N(T *mem, T val, int order) case AtomicExpr::AO__c11_atomic_store: case AtomicExpr::AO__opencl_atomic_store: + case AtomicExpr::AO__hip_atomic_store: case AtomicExpr::AO__atomic_store: case AtomicExpr::AO__atomic_store_n: LibCallName = "__atomic_store"; @@ -1121,6 +1158,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { // T __atomic_load_N(T *mem, int order) case AtomicExpr::AO__c11_atomic_load: case AtomicExpr::AO__opencl_atomic_load: + case AtomicExpr::AO__hip_atomic_load: case AtomicExpr::AO__atomic_load: case AtomicExpr::AO__atomic_load_n: LibCallName = "__atomic_load"; @@ -1133,6 +1171,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { case AtomicExpr::AO__c11_atomic_fetch_add: case AtomicExpr::AO__opencl_atomic_fetch_add: case AtomicExpr::AO__atomic_fetch_add: + case AtomicExpr::AO__hip_atomic_fetch_add: LibCallName = "__atomic_fetch_add"; AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), LoweredMemTy, E->getExprLoc(), TInfo.Width); @@ -1144,6 +1183,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_and: case AtomicExpr::AO__opencl_atomic_fetch_and: + case AtomicExpr::AO__hip_atomic_fetch_and: case AtomicExpr::AO__atomic_fetch_and: LibCallName = "__atomic_fetch_and"; AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), @@ -1156,6 +1196,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_or: case AtomicExpr::AO__opencl_atomic_fetch_or: + case AtomicExpr::AO__hip_atomic_fetch_or: case AtomicExpr::AO__atomic_fetch_or: LibCallName = "__atomic_fetch_or"; AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), @@ -1180,6 +1221,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_xor: case AtomicExpr::AO__opencl_atomic_fetch_xor: + case AtomicExpr::AO__hip_atomic_fetch_xor: case AtomicExpr::AO__atomic_fetch_xor: LibCallName = "__atomic_fetch_xor"; AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), @@ -1190,6 +1232,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_min: case AtomicExpr::AO__atomic_fetch_min: + case AtomicExpr::AO__hip_atomic_fetch_min: case AtomicExpr::AO__opencl_atomic_fetch_min: LibCallName = E->getValueType()->isSignedIntegerType() ? "__atomic_fetch_min" @@ -1202,6 +1245,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_max: case AtomicExpr::AO__atomic_fetch_max: + case AtomicExpr::AO__hip_atomic_fetch_max: case AtomicExpr::AO__opencl_atomic_fetch_max: LibCallName = E->getValueType()->isSignedIntegerType() ? "__atomic_fetch_max" @@ -1291,10 +1335,12 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { bool IsStore = E->getOp() == AtomicExpr::AO__c11_atomic_store || E->getOp() == AtomicExpr::AO__opencl_atomic_store || + E->getOp() == AtomicExpr::AO__hip_atomic_store || E->getOp() == AtomicExpr::AO__atomic_store || E->getOp() == AtomicExpr::AO__atomic_store_n; bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_load || E->getOp() == AtomicExpr::AO__opencl_atomic_load || + E->getOp() == AtomicExpr::AO__hip_atomic_load || E->getOp() == AtomicExpr::AO__atomic_load || E->getOp() == AtomicExpr::AO__atomic_load_n; diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp index 849423c8b9ba..5d6df59cc405 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp @@ -170,8 +170,9 @@ static Value *EmitNontemporalStore(CodeGenFunction &CGF, const CallExpr *E) { // Convert the type of the pointer to a pointer to the stored type. Val = CGF.EmitToMemory(Val, E->getArg(0)->getType()); + unsigned SrcAddrSpace = Address->getType()->getPointerAddressSpace(); Value *BC = CGF.Builder.CreateBitCast( - Address, llvm::PointerType::getUnqual(Val->getType()), "cast"); + Address, llvm::PointerType::get(Val->getType(), SrcAddrSpace), "cast"); LValue LV = CGF.MakeNaturalAlignAddrLValue(BC, E->getArg(0)->getType()); LV.setNontemporal(true); CGF.EmitStoreOfScalar(Val, LV, false); diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGStmtOpenMP.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGStmtOpenMP.cpp index 4f14459e4d28..f6853a22cd36 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -4510,6 +4510,9 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( Address Replacement(CGF.Builder.CreateLoad(Pair.second), CGF.getContext().getDeclAlign(Pair.first)); Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; }); + if (auto *DI = CGF.getDebugInfo()) + DI->EmitDeclareOfAutoVariable(Pair.first, Pair.second.getPointer(), + CGF.Builder, /*UsePointerValue*/ true); } // Adjust mapping for internal locals by mapping actual memory instead of // a pointer to this memory. diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp index 59f3e0270571..9ba1a5c25e81 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp @@ -710,10 +710,25 @@ void CodeGenModule::Release() { 1); } - if (Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_32 || + // Add module metadata for return address signing (ignoring + // non-leaf/all) and stack tagging. These are actually turned on by function + // attributes, but we use module metadata to emit build attributes. This is + // needed for LTO, where the function attributes are inside bitcode + // serialised into a global variable by the time build attributes are + // emitted, so we can't access them. + if (Context.getTargetInfo().hasFeature("ptrauth") && + LangOpts.getSignReturnAddressScope() != + LangOptions::SignReturnAddressScopeKind::None) + getModule().addModuleFlag(llvm::Module::Override, + "sign-return-address-buildattr", 1); + if (LangOpts.Sanitize.has(SanitizerKind::MemTag)) + getModule().addModuleFlag(llvm::Module::Override, + "tag-stack-memory-buildattr", 1); + + if (Arch == llvm::Triple::thumb || Arch == llvm::Triple::thumbeb || + Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_32 || Arch == llvm::Triple::aarch64_be) { - getModule().addModuleFlag(llvm::Module::Error, - "branch-target-enforcement", + getModule().addModuleFlag(llvm::Module::Error, "branch-target-enforcement", LangOpts.BranchTargetEnforcement); getModule().addModuleFlag(llvm::Module::Error, "sign-return-address", @@ -722,9 +737,11 @@ void CodeGenModule::Release() { getModule().addModuleFlag(llvm::Module::Error, "sign-return-address-all", LangOpts.isSignReturnAddressScopeAll()); - getModule().addModuleFlag(llvm::Module::Error, - "sign-return-address-with-bkey", - !LangOpts.isSignReturnAddressWithAKey()); + if (Arch != llvm::Triple::thumb && Arch != llvm::Triple::thumbeb) { + getModule().addModuleFlag(llvm::Module::Error, + "sign-return-address-with-bkey", + !LangOpts.isSignReturnAddressWithAKey()); + } } if (!CodeGenOpts.MemoryProfileOutput.empty()) { @@ -1266,6 +1283,20 @@ static bool isUniqueInternalLinkageDecl(GlobalDecl GD, (CGM.getFunctionLinkage(GD) == llvm::GlobalValue::InternalLinkage); } +static void AppendTargetClonesMangling(const CodeGenModule &CGM, + const TargetClonesAttr *Attr, + unsigned VersionIndex, + raw_ostream &Out) { + Out << '.'; + StringRef FeatureStr = Attr->getFeatureStr(VersionIndex); + if (FeatureStr.startswith("arch=")) + Out << "arch_" << FeatureStr.substr(sizeof("arch=") - 1); + else + Out << FeatureStr; + + Out << '.' << Attr->getMangledIndex(VersionIndex); +} + static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD, const NamedDecl *ND, bool OmitMultiVersionMangling = false) { @@ -1319,6 +1350,10 @@ static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD, case MultiVersionKind::Target: AppendTargetMangling(CGM, FD->getAttr(), Out); break; + case MultiVersionKind::TargetClones: + AppendTargetClonesMangling(CGM, FD->getAttr(), + GD.getMultiVersionIndex(), Out); + break; case MultiVersionKind::None: llvm_unreachable("None multiversion type isn't valid here"); } @@ -1983,8 +2018,9 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, FD = FD ? FD->getMostRecentDecl() : FD; const auto *TD = FD ? FD->getAttr() : nullptr; const auto *SD = FD ? FD->getAttr() : nullptr; + const auto *TC = FD ? FD->getAttr() : nullptr; bool AddedAttr = false; - if (TD || SD) { + if (TD || SD || TC) { llvm::StringMap FeatureMap; getContext().getFunctionFeatureMap(FeatureMap, GD); @@ -3226,6 +3262,12 @@ void CodeGenModule::EmitMultiVersionFunctionDefinition(GlobalDecl GD, for (unsigned I = 0; I < Spec->cpus_size(); ++I) EmitGlobalFunctionDefinition(GD.getWithMultiVersionIndex(I), nullptr); // Requires multiple emits. + } else if (FD->isTargetClonesMultiVersion()) { + auto *Clone = FD->getAttr(); + for (unsigned I = 0; I < Clone->featuresStrs_size(); ++I) + if (Clone->isFirstOfVersion(I)) + EmitGlobalFunctionDefinition(GD.getWithMultiVersionIndex(I), nullptr); + EmitTargetClonesResolver(GD); } else EmitGlobalFunctionDefinition(GD, GV); } @@ -3307,6 +3349,63 @@ llvm::GlobalValue::LinkageTypes getMultiversionLinkage(CodeGenModule &CGM, return llvm::GlobalValue::WeakODRLinkage; } +void CodeGenModule::EmitTargetClonesResolver(GlobalDecl GD) { + const auto *FD = cast(GD.getDecl()); + assert(FD && "Not a FunctionDecl?"); + const auto *TC = FD->getAttr(); + assert(TC && "Not a target_clones Function?"); + + QualType CanonTy = Context.getCanonicalType(FD->getType()); + llvm::Type *DeclTy = getTypes().ConvertType(CanonTy); + + if (const auto *CXXFD = dyn_cast(FD)) { + const CGFunctionInfo &FInfo = getTypes().arrangeCXXMethodDeclaration(CXXFD); + DeclTy = getTypes().GetFunctionType(FInfo); + } + + llvm::Function *ResolverFunc; + if (getTarget().supportsIFunc()) { + auto *IFunc = cast( + GetOrCreateMultiVersionResolver(GD, DeclTy, FD)); + ResolverFunc = cast(IFunc->getResolver()); + } else + ResolverFunc = + cast(GetOrCreateMultiVersionResolver(GD, DeclTy, FD)); + + SmallVector Options; + for (unsigned VersionIndex = 0; VersionIndex < TC->featuresStrs_size(); + ++VersionIndex) { + if (!TC->isFirstOfVersion(VersionIndex)) + continue; + StringRef Version = TC->getFeatureStr(VersionIndex); + StringRef MangledName = + getMangledName(GD.getWithMultiVersionIndex(VersionIndex)); + llvm::Constant *Func = GetGlobalValue(MangledName); + assert(Func && + "Should have already been created before calling resolver emit"); + + StringRef Architecture; + llvm::SmallVector Feature; + + if (Version.startswith("arch=")) + Architecture = Version.drop_front(sizeof("arch=") - 1); + else if (Version != "default") + Feature.push_back(Version); + + Options.emplace_back(cast(Func), Architecture, Feature); + } + + const TargetInfo &TI = getTarget(); + std::stable_sort( + Options.begin(), Options.end(), + [&TI](const CodeGenFunction::MultiVersionResolverOption &LHS, + const CodeGenFunction::MultiVersionResolverOption &RHS) { + return TargetMVPriority(TI, LHS) > TargetMVPriority(TI, RHS); + }); + CodeGenFunction CGF(*this); + CGF.EmitMultiVersionResolver(ResolverFunc, Options); +} + void CodeGenModule::emitMultiVersionFunctions() { std::vector MVFuncsToEmit; MultiVersionFuncs.swap(MVFuncsToEmit); @@ -3511,8 +3610,25 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver( // Since this is the first time we've created this IFunc, make sure // that we put this multiversioned function into the list to be // replaced later if necessary (target multiversioning only). - if (!FD->isCPUDispatchMultiVersion() && !FD->isCPUSpecificMultiVersion()) + if (FD->isTargetMultiVersion()) MultiVersionFuncs.push_back(GD); + else if (FD->isTargetClonesMultiVersion()) { + // In target_clones multiversioning, make sure we emit this if used. + auto DDI = + DeferredDecls.find(getMangledName(GD.getWithMultiVersionIndex(0))); + if (DDI != DeferredDecls.end()) { + addDeferredDeclToEmit(GD); + DeferredDecls.erase(DDI); + } else { + // Emit the symbol of the 1st variant, so that the deferred decls know we + // need it, otherwise the only global value will be the resolver/ifunc, + // which end up getting broken if we search for them with GetGlobalValue'. + GetOrCreateLLVMFunction( + getMangledName(GD.getWithMultiVersionIndex(0)), DeclTy, FD, + /*ForVTable=*/false, /*DontDefer=*/true, + /*IsThunk=*/false, llvm::AttributeList(), ForDefinition); + } + } if (getTarget().supportsIFunc()) { llvm::Type *ResolverType = llvm::FunctionType::get( diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h index fbed22376c82..e1c7f486d334 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h +++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h @@ -1500,6 +1500,7 @@ class CodeGenModule : public CodeGenTypeCache { void EmitAliasDefinition(GlobalDecl GD); void emitIFuncDefinition(GlobalDecl GD); void emitCPUDispatchDefinition(GlobalDecl GD); + void EmitTargetClonesResolver(GlobalDecl GD); void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D); void EmitObjCIvarInitializations(ObjCImplementationDecl *D); diff --git a/contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp b/contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp index 302dc653c46e..36e0319c8ab9 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp @@ -6364,6 +6364,26 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo { const FunctionDecl *FD = dyn_cast_or_null(D); if (!FD) return; + auto *Fn = cast(GV); + + if (const auto *TA = FD->getAttr()) { + ParsedTargetAttr Attr = TA->parse(); + if (!Attr.BranchProtection.empty()) { + TargetInfo::BranchProtectionInfo BPI; + StringRef DiagMsg; + (void)CGM.getTarget().validateBranchProtection(Attr.BranchProtection, + BPI, DiagMsg); + + static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"}; + assert(static_cast(BPI.SignReturnAddr) <= 2 && + "Unexpected SignReturnAddressScopeKind"); + Fn->addFnAttr("sign-return-address", + SignReturnAddrStr[static_cast(BPI.SignReturnAddr)]); + + Fn->addFnAttr("branch-target-enforcement", + BPI.BranchTargetEnforcement ? "true" : "false"); + } + } const ARMInterruptAttr *Attr = FD->getAttr(); if (!Attr) @@ -6379,8 +6399,6 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo { case ARMInterruptAttr::UNDEF: Kind = "UNDEF"; break; } - llvm::Function *Fn = cast(GV); - Fn->addFnAttr("interrupt", Kind); ARMABIInfo::ABIKind ABI = cast(getABIInfo()).getABIKind(); @@ -9339,17 +9357,25 @@ AMDGPUTargetCodeGenInfo::getLLVMSyncScopeID(const LangOptions &LangOpts, llvm::LLVMContext &Ctx) const { std::string Name; switch (Scope) { + case SyncScope::HIPSingleThread: + Name = "singlethread"; + break; + case SyncScope::HIPWavefront: + case SyncScope::OpenCLSubGroup: + Name = "wavefront"; + break; + case SyncScope::HIPWorkgroup: case SyncScope::OpenCLWorkGroup: Name = "workgroup"; break; + case SyncScope::HIPAgent: case SyncScope::OpenCLDevice: Name = "agent"; break; + case SyncScope::HIPSystem: case SyncScope::OpenCLAllSVMDevices: Name = ""; break; - case SyncScope::OpenCLSubGroup: - Name = "wavefront"; } if (Ordering != llvm::AtomicOrdering::SequentiallyConsistent) { diff --git a/contrib/llvm-project/clang/lib/Driver/Driver.cpp b/contrib/llvm-project/clang/lib/Driver/Driver.cpp index 8023d03013a1..d501bd026219 100644 --- a/contrib/llvm-project/clang/lib/Driver/Driver.cpp +++ b/contrib/llvm-project/clang/lib/Driver/Driver.cpp @@ -38,6 +38,7 @@ #include "ToolChains/NaCl.h" #include "ToolChains/NetBSD.h" #include "ToolChains/OpenBSD.h" +#include "ToolChains/PPCFreeBSD.h" #include "ToolChains/PPCLinux.h" #include "ToolChains/PS4CPU.h" #include "ToolChains/RISCVToolchain.h" @@ -5302,7 +5303,11 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, TC = std::make_unique(*this, Target, Args); break; case llvm::Triple::FreeBSD: - TC = std::make_unique(*this, Target, Args); + if (Target.isPPC()) + TC = std::make_unique(*this, Target, + Args); + else + TC = std::make_unique(*this, Target, Args); break; case llvm::Triple::Minix: TC = std::make_unique(*this, Target, Args); diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp index 55518cd7926f..c5aaa067c4f5 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp @@ -403,7 +403,7 @@ shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime, } /// Adds exception related arguments to the driver command arguments. There's a -/// master flag, -fexceptions and also language specific flags to enable/disable +/// main flag, -fexceptions and also language specific flags to enable/disable /// C++ and Objective-C exceptions. This makes it possible to for example /// disable C++ exceptions but enable Objective-C exceptions. static bool addExceptionArgs(const ArgList &Args, types::ID InputType, @@ -1603,6 +1603,49 @@ void RenderARMABI(const Driver &D, const llvm::Triple &Triple, } } +static void CollectARMPACBTIOptions(const Driver &D, const ArgList &Args, + ArgStringList &CmdArgs, bool isAArch64) { + const Arg *A = isAArch64 + ? Args.getLastArg(options::OPT_msign_return_address_EQ, + options::OPT_mbranch_protection_EQ) + : Args.getLastArg(options::OPT_mbranch_protection_EQ); + if (!A) + return; + + StringRef Scope, Key; + bool IndirectBranches; + + if (A->getOption().matches(options::OPT_msign_return_address_EQ)) { + Scope = A->getValue(); + if (!Scope.equals("none") && !Scope.equals("non-leaf") && + !Scope.equals("all")) + D.Diag(diag::err_invalid_branch_protection) + << Scope << A->getAsString(Args); + Key = "a_key"; + IndirectBranches = false; + } else { + StringRef DiagMsg; + llvm::ARM::ParsedBranchProtection PBP; + if (!llvm::ARM::parseBranchProtection(A->getValue(), PBP, DiagMsg)) + D.Diag(diag::err_invalid_branch_protection) + << DiagMsg << A->getAsString(Args); + if (!isAArch64 && PBP.Key == "b_key") + D.Diag(diag::warn_unsupported_branch_protection) + << "b-key" << A->getAsString(Args); + Scope = PBP.Scope; + Key = PBP.Key; + IndirectBranches = PBP.BranchTargetEnforcement; + } + + CmdArgs.push_back( + Args.MakeArgString(Twine("-msign-return-address=") + Scope)); + if (!Scope.equals("none")) + CmdArgs.push_back( + Args.MakeArgString(Twine("-msign-return-address-key=") + Key)); + if (IndirectBranches) + CmdArgs.push_back("-mbranch-target-enforce"); +} + void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args, ArgStringList &CmdArgs, bool KernelOrKext) const { RenderARMABI(getToolChain().getDriver(), Triple, Args, CmdArgs); @@ -1644,6 +1687,10 @@ void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args, CmdArgs.push_back("-mcmse"); AddAAPCSVolatileBitfieldArgs(Args, CmdArgs); + + // Enable/disable return address signing and indirect branch targets. + CollectARMPACBTIOptions(getToolChain().getDriver(), Args, CmdArgs, + false /*isAArch64*/); } void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple, @@ -1783,40 +1830,8 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, } // Enable/disable return address signing and indirect branch targets. - if (Arg *A = Args.getLastArg(options::OPT_msign_return_address_EQ, - options::OPT_mbranch_protection_EQ)) { - - const Driver &D = getToolChain().getDriver(); - - StringRef Scope, Key; - bool IndirectBranches; - - if (A->getOption().matches(options::OPT_msign_return_address_EQ)) { - Scope = A->getValue(); - if (!Scope.equals("none") && !Scope.equals("non-leaf") && - !Scope.equals("all")) - D.Diag(diag::err_invalid_branch_protection) - << Scope << A->getAsString(Args); - Key = "a_key"; - IndirectBranches = false; - } else { - StringRef Err; - llvm::AArch64::ParsedBranchProtection PBP; - if (!llvm::AArch64::parseBranchProtection(A->getValue(), PBP, Err)) - D.Diag(diag::err_invalid_branch_protection) - << Err << A->getAsString(Args); - Scope = PBP.Scope; - Key = PBP.Key; - IndirectBranches = PBP.BranchTargetEnforcement; - } - - CmdArgs.push_back( - Args.MakeArgString(Twine("-msign-return-address=") + Scope)); - CmdArgs.push_back( - Args.MakeArgString(Twine("-msign-return-address-key=") + Key)); - if (IndirectBranches) - CmdArgs.push_back("-mbranch-target-enforce"); - } + CollectARMPACBTIOptions(getToolChain().getDriver(), Args, CmdArgs, + true /*isAArch64*/); // Handle -msve_vector_bits= if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) { @@ -5821,9 +5836,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden_static_local_var, options::OPT_fno_visibility_inlines_hidden_static_local_var); Args.AddLastArg(CmdArgs, options::OPT_fvisibility_global_new_delete_hidden); - Args.AddLastArg(CmdArgs, options::OPT_fnew_infallible); Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ); + if (Args.hasFlag(options::OPT_fnew_infallible, + options::OPT_fno_new_infallible, false)) + CmdArgs.push_back("-fnew-infallible"); + if (Args.hasFlag(options::OPT_fno_operator_names, options::OPT_foperator_names, false)) CmdArgs.push_back("-fno-operator-names"); @@ -5886,7 +5904,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // runtime. if (Args.hasFlag(options::OPT_fopenmp_target_new_runtime, options::OPT_fno_openmp_target_new_runtime, - /*Default=*/false)) + /*Default=*/!getToolChain().getTriple().isAMDGCN())) CmdArgs.push_back("-fopenmp-target-new-runtime"); // When in OpenMP offloading mode, enable debugging on the device. @@ -6659,6 +6677,35 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, A->claim(); } + // Turn -fplugin-arg-pluginname-key=value into + // -plugin-arg-pluginname key=value + // GCC has an actual plugin_argument struct with key/value pairs that it + // passes to its plugins, but we don't, so just pass it on as-is. + // + // The syntax for -fplugin-arg- is ambiguous if both plugin name and + // argument key are allowed to contain dashes. GCC therefore only + // allows dashes in the key. We do the same. + for (const Arg *A : Args.filtered(options::OPT_fplugin_arg)) { + auto ArgValue = StringRef(A->getValue()); + auto FirstDashIndex = ArgValue.find('-'); + StringRef PluginName = ArgValue.substr(0, FirstDashIndex); + StringRef Arg = ArgValue.substr(FirstDashIndex + 1); + + A->claim(); + if (FirstDashIndex == StringRef::npos || Arg.empty()) { + if (PluginName.empty()) { + D.Diag(diag::warn_drv_missing_plugin_name) << A->getAsString(Args); + } else { + D.Diag(diag::warn_drv_missing_plugin_arg) + << PluginName << A->getAsString(Args); + } + continue; + } + + CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-arg-") + PluginName)); + CmdArgs.push_back(Args.MakeArgString(Arg)); + } + // Forward -fpass-plugin=name.so to -cc1. for (const Arg *A : Args.filtered(options::OPT_fpass_plugin_EQ)) { CmdArgs.push_back( diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp index 5397c7a9a0e6..ee573b89bed1 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp @@ -745,7 +745,7 @@ void CudaToolChain::addClangTargetOptions( std::string BitcodeSuffix; if (DriverArgs.hasFlag(options::OPT_fopenmp_target_new_runtime, - options::OPT_fno_openmp_target_new_runtime, false)) + options::OPT_fno_openmp_target_new_runtime, true)) BitcodeSuffix = "new-nvptx-" + GpuArch.str(); else BitcodeSuffix = "nvptx-" + GpuArch.str(); diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Flang.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Flang.cpp index b82c5d7600df..c169e3d45793 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Flang.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Flang.cpp @@ -32,7 +32,8 @@ void Flang::AddFortranDialectOptions(const ArgList &Args, options::OPT_fxor_operator, options::OPT_fno_xor_operator, options::OPT_falternative_parameter_statement, options::OPT_fdefault_real_8, options::OPT_fdefault_integer_8, - options::OPT_fdefault_double_8, options::OPT_flarge_sizes}); + options::OPT_fdefault_double_8, options::OPT_flarge_sizes, + options::OPT_fno_automatic}); } void Flang::AddPreprocessingOptions(const ArgList &Args, diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp index dc05f9893465..d08ea282f6df 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp @@ -391,7 +391,8 @@ FreeBSD::FreeBSD(const Driver &D, const llvm::Triple &Triple, } ToolChain::CXXStdlibType FreeBSD::GetDefaultCXXStdlibType() const { - if (getTriple().getOSMajorVersion() >= 10) + unsigned Major = getTriple().getOSMajorVersion(); + if (Major >= 10 || Major == 0) return ToolChain::CST_Libcxx; return ToolChain::CST_Libstdcxx; } diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp index 0224383e63a1..198774506e5e 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp @@ -421,6 +421,9 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { (Triple.getEnvironment() == llvm::Triple::MuslEABIHF || tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard)) ArchName += "hf"; + if (Arch == llvm::Triple::ppc && + Triple.getSubArch() == llvm::Triple::PPCSubArch_spe) + ArchName = "powerpc-sf"; return "/lib/ld-musl-" + ArchName + ".so.1"; } diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/PPCFreeBSD.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/PPCFreeBSD.cpp new file mode 100644 index 000000000000..8d381c4f1437 --- /dev/null +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/PPCFreeBSD.cpp @@ -0,0 +1,28 @@ +//===-- PPCFreeBSD.cpp - PowerPC ToolChain Implementations ------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "PPCFreeBSD.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Options.h" +#include "llvm/Support/Path.h" + +using namespace clang::driver::toolchains; +using namespace llvm::opt; + +void PPCFreeBSDToolChain::AddClangSystemIncludeArgs( + const ArgList &DriverArgs, ArgStringList &CC1Args) const { + if (!DriverArgs.hasArg(clang::driver::options::OPT_nostdinc) && + !DriverArgs.hasArg(options::OPT_nobuiltininc)) { + const Driver &D = getDriver(); + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "include", "ppc_wrappers"); + addSystemInclude(DriverArgs, CC1Args, P); + } + + FreeBSD::AddClangSystemIncludeArgs(DriverArgs, CC1Args); +} diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/PPCFreeBSD.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/PPCFreeBSD.h new file mode 100644 index 000000000000..d5d9cf4e83a0 --- /dev/null +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/PPCFreeBSD.h @@ -0,0 +1,33 @@ +//===--- PPCFreeBSD.h - PowerPC ToolChain Implementations -------*- 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 LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_PPC_FREEBSD_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_PPC_FREEBSD_H + +#include "FreeBSD.h" + +namespace clang { +namespace driver { +namespace toolchains { + +class LLVM_LIBRARY_VISIBILITY PPCFreeBSDToolChain : public FreeBSD { +public: + PPCFreeBSDToolChain(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args) + : FreeBSD(D, Triple, Args) {} + + void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; +}; + +} // end namespace toolchains +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_PPC_FREEBSD_H diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.h index 82f9523f84fb..4bedabaf267c 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.h @@ -80,6 +80,7 @@ class LLVM_LIBRARY_VISIBILITY PS4CPU : public Generic_ELF { return LangOptions::SSPStrong; } + unsigned GetDefaultDwarfVersion() const override { return 4; } llvm::DebuggerKind getDefaultDebuggerTuning() const override { return llvm::DebuggerKind::SCE; } diff --git a/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp b/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp index 1e4f5690ef24..5073f5105d05 100644 --- a/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp +++ b/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp @@ -1984,9 +1984,17 @@ ContinuationIndenter::createBreakableToken(const FormatToken &Current, } else if (Current.is(TT_LineComment) && (Current.Previous == nullptr || Current.Previous->isNot(TT_ImplicitStringLiteral))) { + bool RegularComments = [&]() { + for (const FormatToken *T = &Current; T && T->is(TT_LineComment); + T = T->Next) { + if (!(T->TokenText.startswith("//") || T->TokenText.startswith("#"))) + return false; + } + return true; + }(); if (!Style.ReflowComments || CommentPragmasRegex.match(Current.TokenText.substr(2)) || - switchesFormatting(Current)) + switchesFormatting(Current) || !RegularComments) return nullptr; return std::make_unique( Current, StartColumn, /*InPPDirective=*/false, Encoding, Style); @@ -2195,11 +2203,10 @@ ContinuationIndenter::breakProtrudingToken(const FormatToken &Current, // When breaking before a tab character, it may be moved by a few columns, // but will still be expanded to the next tab stop, so we don't save any // columns. - if (NewRemainingTokenColumns == RemainingTokenColumns) { + if (NewRemainingTokenColumns >= RemainingTokenColumns) { // FIXME: Do we need to adjust the penalty? break; } - assert(NewRemainingTokenColumns < RemainingTokenColumns); LLVM_DEBUG(llvm::dbgs() << " Breaking at: " << TailOffset + Split.first << ", " << Split.second << "\n"); diff --git a/contrib/llvm-project/clang/lib/Format/Format.cpp b/contrib/llvm-project/clang/lib/Format/Format.cpp index 8ae29c54a762..17de1075aeaa 100644 --- a/contrib/llvm-project/clang/lib/Format/Format.cpp +++ b/contrib/llvm-project/clang/lib/Format/Format.cpp @@ -2988,9 +2988,8 @@ reformat(const FormatStyle &Style, StringRef Code, // JSON only needs the formatting passing. if (Style.isJson()) { std::vector Ranges(1, tooling::Range(0, Code.size())); - auto Env = - Environment::make(Code, FileName, Ranges, FirstStartColumn, - NextStartColumn, LastStartColumn); + auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn, + NextStartColumn, LastStartColumn); if (!Env) return {}; // Perform the actual formatting pass. @@ -3118,9 +3117,7 @@ tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style, auto Env = Environment::make(Code, FileName, Ranges); if (!Env) return {}; - return NamespaceEndCommentsFixer(*Env, Style) - .process() - .first; + return NamespaceEndCommentsFixer(*Env, Style).process().first; } tooling::Replacements sortUsingDeclarations(const FormatStyle &Style, @@ -3130,9 +3127,7 @@ tooling::Replacements sortUsingDeclarations(const FormatStyle &Style, auto Env = Environment::make(Code, FileName, Ranges); if (!Env) return {}; - return UsingDeclarationsSorter(*Env, Style) - .process() - .first; + return UsingDeclarationsSorter(*Env, Style).process().first; } LangOptions getFormattingLangOpts(const FormatStyle &Style) { diff --git a/contrib/llvm-project/clang/lib/Format/FormatToken.h b/contrib/llvm-project/clang/lib/Format/FormatToken.h index 06d51dd95f50..1a2858018fde 100644 --- a/contrib/llvm-project/clang/lib/Format/FormatToken.h +++ b/contrib/llvm-project/clang/lib/Format/FormatToken.h @@ -76,6 +76,7 @@ namespace format { TYPE(LineComment) \ TYPE(MacroBlockBegin) \ TYPE(MacroBlockEnd) \ + TYPE(ModulePartitionColon) \ TYPE(NamespaceMacro) \ TYPE(NonNullAssertion) \ TYPE(NullCoalescingEqual) \ diff --git a/contrib/llvm-project/clang/lib/Format/FormatTokenLexer.cpp b/contrib/llvm-project/clang/lib/Format/FormatTokenLexer.cpp index 8075756cca03..64fbd2d5d45b 100644 --- a/contrib/llvm-project/clang/lib/Format/FormatTokenLexer.cpp +++ b/contrib/llvm-project/clang/lib/Format/FormatTokenLexer.cpp @@ -37,27 +37,40 @@ FormatTokenLexer::FormatTokenLexer( getFormattingLangOpts(Style))); Lex->SetKeepWhitespaceMode(true); - for (const std::string &ForEachMacro : Style.ForEachMacros) - Macros.insert({&IdentTable.get(ForEachMacro), TT_ForEachMacro}); - for (const std::string &IfMacro : Style.IfMacros) - Macros.insert({&IdentTable.get(IfMacro), TT_IfMacro}); - for (const std::string &AttributeMacro : Style.AttributeMacros) - Macros.insert({&IdentTable.get(AttributeMacro), TT_AttributeMacro}); - for (const std::string &StatementMacro : Style.StatementMacros) - Macros.insert({&IdentTable.get(StatementMacro), TT_StatementMacro}); - for (const std::string &TypenameMacro : Style.TypenameMacros) - Macros.insert({&IdentTable.get(TypenameMacro), TT_TypenameMacro}); - for (const std::string &NamespaceMacro : Style.NamespaceMacros) - Macros.insert({&IdentTable.get(NamespaceMacro), TT_NamespaceMacro}); + for (const std::string &ForEachMacro : Style.ForEachMacros) { + auto Identifier = &IdentTable.get(ForEachMacro); + Macros.insert({Identifier, TT_ForEachMacro}); + } + for (const std::string &IfMacro : Style.IfMacros) { + auto Identifier = &IdentTable.get(IfMacro); + Macros.insert({Identifier, TT_IfMacro}); + } + for (const std::string &AttributeMacro : Style.AttributeMacros) { + auto Identifier = &IdentTable.get(AttributeMacro); + Macros.insert({Identifier, TT_AttributeMacro}); + } + for (const std::string &StatementMacro : Style.StatementMacros) { + auto Identifier = &IdentTable.get(StatementMacro); + Macros.insert({Identifier, TT_StatementMacro}); + } + for (const std::string &TypenameMacro : Style.TypenameMacros) { + auto Identifier = &IdentTable.get(TypenameMacro); + Macros.insert({Identifier, TT_TypenameMacro}); + } + for (const std::string &NamespaceMacro : Style.NamespaceMacros) { + auto Identifier = &IdentTable.get(NamespaceMacro); + Macros.insert({Identifier, TT_NamespaceMacro}); + } for (const std::string &WhitespaceSensitiveMacro : Style.WhitespaceSensitiveMacros) { - Macros.insert( - {&IdentTable.get(WhitespaceSensitiveMacro), TT_UntouchableMacroFunc}); + auto Identifier = &IdentTable.get(WhitespaceSensitiveMacro); + Macros.insert({Identifier, TT_UntouchableMacroFunc}); } for (const std::string &StatementAttributeLikeMacro : - Style.StatementAttributeLikeMacros) - Macros.insert({&IdentTable.get(StatementAttributeLikeMacro), - TT_StatementAttributeLikeMacro}); + Style.StatementAttributeLikeMacros) { + auto Identifier = &IdentTable.get(StatementAttributeLikeMacro); + Macros.insert({Identifier, TT_StatementAttributeLikeMacro}); + } } ArrayRef FormatTokenLexer::lex() { @@ -739,6 +752,8 @@ bool FormatTokenLexer::tryMerge_TMacro() { Tokens.pop_back(); Tokens.pop_back(); Tokens.back() = String; + if (FirstInLineIndex >= Tokens.size()) + FirstInLineIndex = Tokens.size() - 1; return true; } diff --git a/contrib/llvm-project/clang/lib/Format/SortJavaScriptImports.cpp b/contrib/llvm-project/clang/lib/Format/SortJavaScriptImports.cpp index 515cfce725a4..77dc0d683e5f 100644 --- a/contrib/llvm-project/clang/lib/Format/SortJavaScriptImports.cpp +++ b/contrib/llvm-project/clang/lib/Format/SortJavaScriptImports.cpp @@ -553,9 +553,7 @@ tooling::Replacements sortJavaScriptImports(const FormatStyle &Style, auto Env = Environment::make(Code, FileName, Ranges); if (!Env) return {}; - return JavaScriptImportSorter(*Env, Style) - .process() - .first; + return JavaScriptImportSorter(*Env, Style).process().first; } } // end namespace format diff --git a/contrib/llvm-project/clang/lib/Format/TokenAnalyzer.cpp b/contrib/llvm-project/clang/lib/Format/TokenAnalyzer.cpp index a619c6d939e9..d83e837ca134 100644 --- a/contrib/llvm-project/clang/lib/Format/TokenAnalyzer.cpp +++ b/contrib/llvm-project/clang/lib/Format/TokenAnalyzer.cpp @@ -37,7 +37,7 @@ namespace format { // FIXME: Instead of printing the diagnostic we should store it and have a // better way to return errors through the format APIs. -class FatalDiagnosticConsumer: public DiagnosticConsumer { +class FatalDiagnosticConsumer : public DiagnosticConsumer { public: void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) override { @@ -71,7 +71,8 @@ Environment::make(StringRef Code, StringRef FileName, } // Validate that we can get the buffer data without a fatal error. Env->SM.getBufferData(Env->ID); - if (Diags.fatalError()) return nullptr; + if (Diags.fatalError()) + return nullptr; return Env; } @@ -80,8 +81,7 @@ Environment::Environment(StringRef Code, StringRef FileName, unsigned LastStartColumn) : VirtualSM(new SourceManagerForFile(FileName, Code)), SM(VirtualSM->get()), ID(VirtualSM->get().getMainFileID()), FirstStartColumn(FirstStartColumn), - NextStartColumn(NextStartColumn), LastStartColumn(LastStartColumn) { -} + NextStartColumn(NextStartColumn), LastStartColumn(LastStartColumn) {} TokenAnalyzer::TokenAnalyzer(const Environment &Env, const FormatStyle &Style) : Style(Style), Env(Env), diff --git a/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp b/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp index 3897241cb858..a94d8cdc3b04 100644 --- a/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp +++ b/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp @@ -314,10 +314,11 @@ class AnnotatingParser { // // void (*FunctionPointer)(void); // void (&FunctionReference)(void); + // void (&&FunctionReference)(void); // void (^ObjCBlock)(void); bool MightBeFunctionType = !Contexts[Contexts.size() - 2].IsExpression; bool ProbablyFunctionType = - CurrentToken->isOneOf(tok::star, tok::amp, tok::caret); + CurrentToken->isOneOf(tok::star, tok::amp, tok::ampamp, tok::caret); bool HasMultipleLines = false; bool HasMultipleParametersOnALine = false; bool MightBeObjCForRangeLoop = @@ -902,9 +903,13 @@ class AnnotatingParser { break; } } - if (Contexts.back().ColonIsDictLiteral || - Style.Language == FormatStyle::LK_Proto || - Style.Language == FormatStyle::LK_TextProto) { + if (Line.First->isOneOf(Keywords.kw_module, Keywords.kw_import) || + Line.First->startsSequence(tok::kw_export, Keywords.kw_module) || + Line.First->startsSequence(tok::kw_export, Keywords.kw_import)) { + Tok->setType(TT_ModulePartitionColon); + } else if (Contexts.back().ColonIsDictLiteral || + Style.Language == FormatStyle::LK_Proto || + Style.Language == FormatStyle::LK_TextProto) { Tok->setType(TT_DictLiteral); if (Style.Language == FormatStyle::LK_TextProto) { if (FormatToken *Previous = Tok->getPreviousNonComment()) @@ -946,11 +951,15 @@ class AnnotatingParser { !Line.First->isOneOf(tok::kw_enum, tok::kw_case, tok::kw_default)) { FormatToken *Prev = Tok->getPreviousNonComment(); + if (!Prev) + break; if (Prev->isOneOf(tok::r_paren, tok::kw_noexcept)) Tok->setType(TT_CtorInitializerColon); else if (Prev->is(tok::kw_try)) { // Member initializer list within function try block. FormatToken *PrevPrev = Prev->getPreviousNonComment(); + if (!PrevPrev) + break; if (PrevPrev && PrevPrev->isOneOf(tok::r_paren, tok::kw_noexcept)) Tok->setType(TT_CtorInitializerColon); } else @@ -995,6 +1004,8 @@ class AnnotatingParser { if (CurrentToken && CurrentToken->is(Keywords.kw_await)) next(); } + if (Style.isCpp() && CurrentToken && CurrentToken->is(tok::kw_co_await)) + next(); Contexts.back().ColonIsForRangeExpr = true; next(); if (!parseParens()) @@ -1578,6 +1589,8 @@ class AnnotatingParser { if (TemplateCloser->is(tok::l_paren)) { // No Matching Paren yet so skip to matching paren TemplateCloser = untilMatchingParen(TemplateCloser); + if (!TemplateCloser) + break; } if (TemplateCloser->is(tok::less)) NestingLevel++; @@ -2336,16 +2349,15 @@ void TokenAnnotator::setCommentLineLevels( if (NextNonCommentLine && CommentLine && NextNonCommentLine->First->NewlinesBefore <= 1 && NextNonCommentLine->First->OriginalColumn == - AL->First->OriginalColumn) { + AL->First->OriginalColumn) { // Align comments for preprocessor lines with the # in column 0 if // preprocessor lines are not indented. Otherwise, align with the next // line. - AL->Level = - (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash && - (NextNonCommentLine->Type == LT_PreprocessorDirective || - NextNonCommentLine->Type == LT_ImportStatement)) - ? 0 - : NextNonCommentLine->Level; + AL->Level = (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash && + (NextNonCommentLine->Type == LT_PreprocessorDirective || + NextNonCommentLine->Type == LT_ImportStatement)) + ? 0 + : NextNonCommentLine->Level; } else { NextNonCommentLine = AL->First->isNot(tok::r_brace) ? AL : nullptr; } @@ -2639,8 +2651,8 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { if (Current->Role) Current->Role->precomputeFormattingInfos(Current); if (Current->MatchingParen && - Current->MatchingParen->opensBlockOrBlockTypeList(Style)) { - assert(IndentLevel > 0); + Current->MatchingParen->opensBlockOrBlockTypeList(Style) && + IndentLevel > 0) { --IndentLevel; } Current->IndentLevel = IndentLevel; @@ -2942,6 +2954,14 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, if (Left.is(tok::kw_auto) && Right.isOneOf(tok::l_paren, tok::l_brace)) return false; + // operator co_await(x) + if (Right.is(tok::l_paren) && Left.is(tok::kw_co_await) && Left.Previous && + Left.Previous->is(tok::kw_operator)) + return false; + // co_await (x), co_yield (x), co_return (x) + if (Left.isOneOf(tok::kw_co_await, tok::kw_co_yield, tok::kw_co_return) && + Right.isNot(tok::semi)) + return true; // requires clause Concept1 && Concept2 if (Left.is(TT_ConstraintJunctions) && Right.is(tok::identifier)) return true; @@ -3159,9 +3179,13 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, if (Left.isIf(Line.Type != LT_PreprocessorDirective)) return Style.SpaceBeforeParensOptions.AfterControlStatements || spaceRequiredBeforeParens(Right); + + // TODO add Operator overloading specific Options to + // SpaceBeforeParensOptions + if (Right.is(TT_OverloadedOperatorLParen)) + return spaceRequiredBeforeParens(Right); // Function declaration or definition - if (Line.MightBeFunctionDecl && (Left.is(TT_FunctionDeclarationName) || - Right.is(TT_OverloadedOperatorLParen))) { + if (Line.MightBeFunctionDecl && (Left.is(TT_FunctionDeclarationName))) { if (Line.mightBeFunctionDefinition()) return Style.SpaceBeforeParensOptions.AfterFunctionDefinitionName || spaceRequiredBeforeParens(Right); @@ -3238,9 +3262,35 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, auto HasExistingWhitespace = [&Right]() { return Right.WhitespaceRange.getBegin() != Right.WhitespaceRange.getEnd(); }; + if (Right.Tok.getIdentifierInfo() && Left.Tok.getIdentifierInfo()) return true; // Never ever merge two identifiers. + + // Leave a space between * and /* to avoid C4138 `comment end` found outside + // of comment. + if (Left.is(tok::star) && Right.is(tok::comment)) + return true; + if (Style.isCpp()) { + // Space between import . + // or import .....; + if (Left.is(Keywords.kw_import) && Right.isOneOf(tok::less, tok::ellipsis)) + return true; + // No space between module :. + if (Left.isOneOf(Keywords.kw_module, Keywords.kw_import) && + Right.is(TT_ModulePartitionColon)) + return true; + // No space between import foo:bar but keep a space between import :bar; + if (Left.is(tok::identifier) && Right.is(TT_ModulePartitionColon)) + return false; + // No space between :bar; + if (Left.is(TT_ModulePartitionColon) && + Right.isOneOf(tok::identifier, tok::kw_private)) + return false; + if (Left.is(tok::ellipsis) && Right.is(tok::identifier) && + Line.First->is(Keywords.kw_import)) + return false; + if (Left.is(tok::kw_operator)) return Right.is(tok::coloncolon); if (Right.is(tok::l_brace) && Right.is(BK_BracedInit) && diff --git a/contrib/llvm-project/clang/lib/Format/UnwrappedLineFormatter.cpp b/contrib/llvm-project/clang/lib/Format/UnwrappedLineFormatter.cpp index 299536cd806e..d099cfee9dea 100644 --- a/contrib/llvm-project/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/contrib/llvm-project/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -320,9 +320,9 @@ class LineJoiner { } // Try to merge a control statement block with left brace wrapped if (I[1]->First->is(tok::l_brace) && - (TheLine->First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for, - tok::kw_switch, tok::kw_try, tok::kw_do, - TT_ForEachMacro) || + (TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while, + tok::kw_for, tok::kw_switch, tok::kw_try, + tok::kw_do, TT_ForEachMacro) || (TheLine->First->is(tok::r_brace) && TheLine->First->Next && TheLine->First->Next->isOneOf(tok::kw_else, tok::kw_catch))) && Style.BraceWrapping.AfterControlStatement == @@ -335,7 +335,7 @@ class LineJoiner { ? 1 : 0; } else if (I[1]->First->is(tok::l_brace) && - TheLine->First->isOneOf(tok::kw_if, tok::kw_while, + TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while, tok::kw_for)) { return (Style.BraceWrapping.AfterControlStatement == FormatStyle::BWACS_Always) @@ -569,7 +569,7 @@ class LineJoiner { // Check that the current line allows merging. This depends on whether we // are in a control flow statements as well as several style flags. - if (Line.First->isOneOf(tok::kw_else, tok::kw_case) || + if (Line.First->is(tok::kw_case) || (Line.First->Next && Line.First->Next->is(tok::kw_else))) return 0; // default: in switch statement @@ -578,20 +578,21 @@ class LineJoiner { if (Tok && Tok->is(tok::colon)) return 0; } - if (Line.First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::kw_try, - tok::kw___try, tok::kw_catch, tok::kw___finally, - tok::kw_for, tok::r_brace, Keywords.kw___except)) { + if (Line.First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while, tok::kw_do, + tok::kw_try, tok::kw___try, tok::kw_catch, + tok::kw___finally, tok::kw_for, tok::r_brace, + Keywords.kw___except)) { if (Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never) return 0; // Don't merge when we can't except the case when // the control statement block is empty if (!Style.AllowShortIfStatementsOnASingleLine && - Line.startsWith(tok::kw_if) && + Line.First->isOneOf(tok::kw_if, tok::kw_else) && !Style.BraceWrapping.AfterControlStatement && !I[1]->First->is(tok::r_brace)) return 0; if (!Style.AllowShortIfStatementsOnASingleLine && - Line.startsWith(tok::kw_if) && + Line.First->isOneOf(tok::kw_if, tok::kw_else) && Style.BraceWrapping.AfterControlStatement == FormatStyle::BWACS_Always && I + 2 != E && !I[2]->First->is(tok::r_brace)) @@ -676,7 +677,7 @@ class LineJoiner { // { <-- current Line // baz(); // } - if (Line.First == Line.Last && + if (Line.First == Line.Last && Line.First->isNot(TT_FunctionLBrace) && Style.BraceWrapping.AfterControlStatement == FormatStyle::BWACS_MultiLine) return 0; diff --git a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp index 28d925858f77..5b9fe267aae6 100644 --- a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp +++ b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp @@ -28,9 +28,28 @@ namespace format { class FormatTokenSource { public: virtual ~FormatTokenSource() {} + + // Returns the next token in the token stream. virtual FormatToken *getNextToken() = 0; + // Returns the token precedint the token returned by the last call to + // getNextToken() in the token stream, or nullptr if no such token exists. + virtual FormatToken *getPreviousToken() = 0; + + // Returns the token that would be returned by the next call to + // getNextToken(). + virtual FormatToken *peekNextToken() = 0; + + // Returns whether we are at the end of the file. + // This can be different from whether getNextToken() returned an eof token + // when the FormatTokenSource is a view on a part of the token stream. + virtual bool isEOF() = 0; + + // Gets the current position in the token stream, to be used by setPosition(). virtual unsigned getPosition() = 0; + + // Resets the token stream to the state it was in when getPosition() returned + // Position, and return the token at that position in the stream. virtual FormatToken *setPosition(unsigned Position) = 0; }; @@ -108,6 +127,18 @@ class ScopedMacroState : public FormatTokenSource { return Token; } + FormatToken *getPreviousToken() override { + return PreviousTokenSource->getPreviousToken(); + } + + FormatToken *peekNextToken() override { + if (eof()) + return &FakeEOF; + return PreviousTokenSource->peekNextToken(); + } + + bool isEOF() override { return PreviousTokenSource->isEOF(); } + unsigned getPosition() override { return PreviousTokenSource->getPosition(); } FormatToken *setPosition(unsigned Position) override { @@ -199,16 +230,45 @@ class IndexedTokenSource : public FormatTokenSource { : Tokens(Tokens), Position(-1) {} FormatToken *getNextToken() override { + if (Position >= 0 && Tokens[Position]->is(tok::eof)) { + LLVM_DEBUG({ + llvm::dbgs() << "Next "; + dbgToken(Position); + }); + return Tokens[Position]; + } ++Position; + LLVM_DEBUG({ + llvm::dbgs() << "Next "; + dbgToken(Position); + }); return Tokens[Position]; } + FormatToken *getPreviousToken() override { + assert(Position > 0); + return Tokens[Position - 1]; + } + + FormatToken *peekNextToken() override { + int Next = Position + 1; + LLVM_DEBUG({ + llvm::dbgs() << "Peeking "; + dbgToken(Next); + }); + return Tokens[Next]; + } + + bool isEOF() override { return Tokens[Position]->is(tok::eof); } + unsigned getPosition() override { + LLVM_DEBUG(llvm::dbgs() << "Getting Position: " << Position << "\n"); assert(Position >= 0); return Position; } FormatToken *setPosition(unsigned P) override { + LLVM_DEBUG(llvm::dbgs() << "Setting Position: " << P << "\n"); Position = P; return Tokens[Position]; } @@ -216,6 +276,13 @@ class IndexedTokenSource : public FormatTokenSource { void reset() { Position = -1; } private: + void dbgToken(int Position, llvm::StringRef Indent = "") { + FormatToken *Tok = Tokens[Position]; + llvm::dbgs() << Indent << "[" << Position + << "] Token: " << Tok->Tok.getName() << " / " << Tok->TokenText + << ", Macro: " << !!Tok->MacroCtx << "\n"; + } + ArrayRef Tokens; int Position; }; @@ -399,7 +466,7 @@ void UnwrappedLineParser::parseLevel(bool HasOpeningBrace) { FormatToken *Next; do { Next = Tokens->getNextToken(); - } while (Next && Next->is(tok::comment)); + } while (Next->is(tok::comment)); FormatTok = Tokens->setPosition(StoredPosition); if (Next && Next->isNot(tok::colon)) { // default not followed by ':' is not a case label; treat it like @@ -875,10 +942,7 @@ void UnwrappedLineParser::parsePPEndIf() { parsePPUnknown(); // If the #endif of a potential include guard is the last thing in the file, // then we found an include guard. - unsigned TokenPosition = Tokens->getPosition(); - FormatToken *PeekNext = AllTokens[TokenPosition]; - if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && - PeekNext->is(tok::eof) && + if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && Tokens->isEOF() && Style.IndentPPDirectives != FormatStyle::PPDIS_None) IncludeGuard = IG_Found; } @@ -1050,6 +1114,35 @@ static bool isC78ParameterDecl(const FormatToken *Tok, const FormatToken *Next, return Tok->Previous && Tok->Previous->isOneOf(tok::l_paren, tok::comma); } +void UnwrappedLineParser::parseModuleImport() { + nextToken(); + while (!eof()) { + if (FormatTok->is(tok::colon)) { + FormatTok->setType(TT_ModulePartitionColon); + } + // Handle import as we would an include statement. + else if (FormatTok->is(tok::less)) { + nextToken(); + while (!FormatTok->isOneOf(tok::semi, tok::greater, tok::eof)) { + // Mark tokens up to the trailing line comments as implicit string + // literals. + if (FormatTok->isNot(tok::comment) && + !FormatTok->TokenText.startswith("//")) + FormatTok->setType(TT_ImplicitStringLiteral); + nextToken(); + } + } + if (FormatTok->is(tok::semi)) { + nextToken(); + break; + } + nextToken(); + } + + addUnwrappedLine(); + return; +} + // readTokenWithJavaScriptASI reads the next token and terminates the current // line if JavaScript Automatic Semicolon Insertion must // happen between the current token and the next token. @@ -1097,7 +1190,6 @@ void UnwrappedLineParser::readTokenWithJavaScriptASI() { } void UnwrappedLineParser::parseStructuralElement(bool IsTopLevel) { - assert(!FormatTok->is(tok::l_brace)); if (Style.Language == FormatStyle::LK_TableGen && FormatTok->is(tok::pp_include)) { nextToken(); @@ -1249,6 +1341,10 @@ void UnwrappedLineParser::parseStructuralElement(bool IsTopLevel) { addUnwrappedLine(); return; } + if (Style.isCpp()) { + parseModuleImport(); + return; + } } if (Style.isCpp() && FormatTok->isOneOf(Keywords.kw_signals, Keywords.kw_qsignals, @@ -1402,9 +1498,7 @@ void UnwrappedLineParser::parseStructuralElement(bool IsTopLevel) { // declaration. if (!IsTopLevel || !Style.isCpp() || !Previous || FormatTok->is(tok::eof)) break; - const unsigned Position = Tokens->getPosition() + 1; - assert(Position < AllTokens.size()); - if (isC78ParameterDecl(FormatTok, AllTokens[Position], Previous)) { + if (isC78ParameterDecl(FormatTok, Tokens->peekNextToken(), Previous)) { addUnwrappedLine(); return; } @@ -1488,7 +1582,7 @@ void UnwrappedLineParser::parseStructuralElement(bool IsTopLevel) { unsigned StoredPosition = Tokens->getPosition(); FormatToken *Next = Tokens->getNextToken(); FormatTok = Tokens->setPosition(StoredPosition); - if (Next && !mustBeJSIdent(Keywords, Next)) { + if (!mustBeJSIdent(Keywords, Next)) { nextToken(); break; } @@ -2099,8 +2193,8 @@ void UnwrappedLineParser::parseIfThenElse() { parseBlock(); addUnwrappedLine(); } else if (FormatTok->Tok.is(tok::kw_if)) { - FormatToken *Previous = AllTokens[Tokens->getPosition() - 1]; - bool PrecededByComment = Previous->is(tok::comment); + FormatToken *Previous = Tokens->getPreviousToken(); + bool PrecededByComment = Previous && Previous->is(tok::comment); if (PrecededByComment) { addUnwrappedLine(); ++Line->Level; @@ -2305,6 +2399,8 @@ void UnwrappedLineParser::parseForOrWhileLoop() { if (Style.Language == FormatStyle::LK_JavaScript && FormatTok->is(Keywords.kw_await)) nextToken(); + if (Style.isCpp() && FormatTok->is(tok::kw_co_await)) + nextToken(); if (FormatTok->Tok.is(tok::l_paren)) parseParens(); if (FormatTok->Tok.is(tok::l_brace)) { @@ -2653,23 +2749,25 @@ bool UnwrappedLineParser::tryToParseSimpleAttribute() { ScopedTokenPosition AutoPosition(Tokens); FormatToken *Tok = Tokens->getNextToken(); // We already read the first [ check for the second. - if (Tok && !Tok->is(tok::l_square)) { + if (!Tok->is(tok::l_square)) { return false; } // Double check that the attribute is just something // fairly simple. - while (Tok) { + while (Tok->isNot(tok::eof)) { if (Tok->is(tok::r_square)) { break; } Tok = Tokens->getNextToken(); } + if (Tok->is(tok::eof)) + return false; Tok = Tokens->getNextToken(); - if (Tok && !Tok->is(tok::r_square)) { + if (!Tok->is(tok::r_square)) { return false; } Tok = Tokens->getNextToken(); - if (Tok && Tok->is(tok::semi)) { + if (Tok->is(tok::semi)) { return false; } return true; @@ -2682,7 +2780,7 @@ void UnwrappedLineParser::parseJavaEnumBody() { unsigned StoredPosition = Tokens->getPosition(); bool IsSimple = true; FormatToken *Tok = Tokens->getNextToken(); - while (Tok) { + while (!Tok->is(tok::eof)) { if (Tok->is(tok::r_brace)) break; if (Tok->isOneOf(tok::l_brace, tok::semi)) { @@ -3292,6 +3390,20 @@ void UnwrappedLineParser::readToken(int LevelDifference) { do { FormatTok = Tokens->getNextToken(); assert(FormatTok); + while (FormatTok->getType() == TT_ConflictStart || + FormatTok->getType() == TT_ConflictEnd || + FormatTok->getType() == TT_ConflictAlternative) { + if (FormatTok->getType() == TT_ConflictStart) { + conditionalCompilationStart(/*Unreachable=*/false); + } else if (FormatTok->getType() == TT_ConflictAlternative) { + conditionalCompilationAlternative(); + } else if (FormatTok->getType() == TT_ConflictEnd) { + conditionalCompilationEnd(); + } + FormatTok = Tokens->getNextToken(); + FormatTok->MustBreakBefore = true; + } + while (!Line->InPPDirective && FormatTok->Tok.is(tok::hash) && (FormatTok->HasUnescapedNewline || FormatTok->IsFirst)) { distributeComments(Comments, FormatTok); @@ -3313,19 +3425,6 @@ void UnwrappedLineParser::readToken(int LevelDifference) { flushComments(isOnNewLine(*FormatTok)); parsePPDirective(); } - while (FormatTok->getType() == TT_ConflictStart || - FormatTok->getType() == TT_ConflictEnd || - FormatTok->getType() == TT_ConflictAlternative) { - if (FormatTok->getType() == TT_ConflictStart) { - conditionalCompilationStart(/*Unreachable=*/false); - } else if (FormatTok->getType() == TT_ConflictAlternative) { - conditionalCompilationAlternative(); - } else if (FormatTok->getType() == TT_ConflictEnd) { - conditionalCompilationEnd(); - } - FormatTok = Tokens->getNextToken(); - FormatTok->MustBreakBefore = true; - } if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) && !Line->InPPDirective) { diff --git a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h index bcae0f3ad258..b4c082654597 100644 --- a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h +++ b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h @@ -110,6 +110,7 @@ class UnwrappedLineParser { void parseCaseLabel(); void parseSwitch(); void parseNamespace(); + void parseModuleImport(); void parseNew(); void parseAccessSpecifier(); bool parseEnum(); diff --git a/contrib/llvm-project/clang/lib/Format/WhitespaceManager.cpp b/contrib/llvm-project/clang/lib/Format/WhitespaceManager.cpp index 74136d2f5caa..fae8a1c3fdc6 100644 --- a/contrib/llvm-project/clang/lib/Format/WhitespaceManager.cpp +++ b/contrib/llvm-project/clang/lib/Format/WhitespaceManager.cpp @@ -372,8 +372,6 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End, if (ContinuedStringLiteral) Changes[i].Spaces += Shift; - assert(Shift >= 0); - Changes[i].StartOfTokenColumn += Shift; if (i + 1 != Changes.size()) Changes[i + 1].PreviousEndOfTokenColumn += Shift; @@ -915,7 +913,8 @@ void WhitespaceManager::alignTrailingComments(unsigned Start, unsigned End, Changes[i].StartOfBlockComment->StartOfTokenColumn - Changes[i].StartOfTokenColumn; } - assert(Shift >= 0); + if (Shift < 0) + continue; Changes[i].Spaces += Shift; if (i + 1 != Changes.size()) Changes[i + 1].PreviousEndOfTokenColumn += Shift; @@ -1270,10 +1269,10 @@ WhitespaceManager::linkCells(CellDescriptions &&CellDesc) { void WhitespaceManager::generateChanges() { for (unsigned i = 0, e = Changes.size(); i != e; ++i) { const Change &C = Changes[i]; - if (i > 0) { - assert(Changes[i - 1].OriginalWhitespaceRange.getBegin() != - C.OriginalWhitespaceRange.getBegin() && - "Generating two replacements for the same location"); + if (i > 0 && Changes[i - 1].OriginalWhitespaceRange.getBegin() == + C.OriginalWhitespaceRange.getBegin()) { + // Do not generate two replacements for the same location. + continue; } if (C.CreateReplacement) { std::string ReplacementText = C.PreviousLinePostfix; diff --git a/contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp b/contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp index 0ecb024fc6b9..0c153446142e 100644 --- a/contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp @@ -505,6 +505,11 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, if (LangOpts.HIP) { Builder.defineMacro("__HIP__"); Builder.defineMacro("__HIPCC__"); + Builder.defineMacro("__HIP_MEMORY_SCOPE_SINGLETHREAD", "1"); + Builder.defineMacro("__HIP_MEMORY_SCOPE_WAVEFRONT", "2"); + Builder.defineMacro("__HIP_MEMORY_SCOPE_WORKGROUP", "3"); + Builder.defineMacro("__HIP_MEMORY_SCOPE_AGENT", "4"); + Builder.defineMacro("__HIP_MEMORY_SCOPE_SYSTEM", "5"); if (LangOpts.CUDAIsDevice) Builder.defineMacro("__HIP_DEVICE_COMPILE__"); } diff --git a/contrib/llvm-project/clang/lib/Frontend/PrecompiledPreamble.cpp b/contrib/llvm-project/clang/lib/Frontend/PrecompiledPreamble.cpp index af82ab3f5558..8aa80a4c96fb 100644 --- a/contrib/llvm-project/clang/lib/Frontend/PrecompiledPreamble.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/PrecompiledPreamble.cpp @@ -412,10 +412,13 @@ llvm::ErrorOr PrecompiledPreamble::Build( std::unique_ptr Act; Act.reset(new PrecompilePreambleAction( StoreInMemory ? &Storage.asMemory().Data : nullptr, Callbacks)); - Callbacks.BeforeExecute(*Clang); if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) return BuildPreambleError::BeginSourceFileFailed; + // Performed after BeginSourceFile to ensure Clang->Preprocessor can be + // referenced in the callback. + Callbacks.BeforeExecute(*Clang); + std::unique_ptr DelegatedPPCallbacks = Callbacks.createPPCallbacks(); if (DelegatedPPCallbacks) diff --git a/contrib/llvm-project/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/contrib/llvm-project/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp index 626ec4d71ccd..b4487f004715 100644 --- a/contrib/llvm-project/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -633,7 +633,7 @@ static bool IsHeaderFile(const std::string &Filename) { return false; } - std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end()); + std::string Ext = Filename.substr(DotPos + 1); // C header: .h // C++ header: .hh or .H; return Ext == "h" || Ext == "hh" || Ext == "H"; diff --git a/contrib/llvm-project/clang/lib/Frontend/Rewrite/RewriteObjC.cpp b/contrib/llvm-project/clang/lib/Frontend/Rewrite/RewriteObjC.cpp index 0750d36b02ac..b2ecb42c43dd 100644 --- a/contrib/llvm-project/clang/lib/Frontend/Rewrite/RewriteObjC.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/Rewrite/RewriteObjC.cpp @@ -569,7 +569,7 @@ static bool IsHeaderFile(const std::string &Filename) { return false; } - std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end()); + std::string Ext = Filename.substr(DotPos + 1); // C header: .h // C++ header: .hh or .H; return Ext == "h" || Ext == "hh" || Ext == "H"; diff --git a/contrib/llvm-project/clang/lib/Headers/altivec.h b/contrib/llvm-project/clang/lib/Headers/altivec.h index fb808d7b0a4f..55195b0781fb 100644 --- a/contrib/llvm-project/clang/lib/Headers/altivec.h +++ b/contrib/llvm-project/clang/lib/Headers/altivec.h @@ -19,6 +19,10 @@ #define __CR6_EQ_REV 1 #define __CR6_LT 2 #define __CR6_LT_REV 3 +#define __CR6_GT 4 +#define __CR6_GT_REV 5 +#define __CR6_SO 6 +#define __CR6_SO_REV 7 /* Constants for vec_test_data_class */ #define __VEC_CLASS_FP_SUBNORMAL_N (1 << 0) @@ -8413,9 +8417,20 @@ static __inline__ vector float __ATTRS_o_ai vec_round(vector float __a) { } #ifdef __VSX__ +#ifdef __XL_COMPAT_ALTIVEC__ +static __inline__ vector double __ATTRS_o_ai vec_rint(vector double __a); +static __inline__ vector double __ATTRS_o_ai vec_round(vector double __a) { + double __fpscr = __builtin_readflm(); + __builtin_setrnd(0); + vector double __rounded = vec_rint(__a); + __builtin_setflm(__fpscr); + return __rounded; +} +#else static __inline__ vector double __ATTRS_o_ai vec_round(vector double __a) { return __builtin_vsx_xvrdpi(__a); } +#endif /* vec_rint */ @@ -19026,6 +19041,51 @@ vec_sra(vector signed __int128 __a, vector unsigned __int128 __b) { #endif /* __SIZEOF_INT128__ */ #endif /* __POWER10_VECTOR__ */ +#ifdef __POWER8_VECTOR__ +#define __bcdadd(__a, __b, __ps) __builtin_ppc_bcdadd((__a), (__b), (__ps)) +#define __bcdsub(__a, __b, __ps) __builtin_ppc_bcdsub((__a), (__b), (__ps)) + +static __inline__ long __bcdadd_ofl(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_ppc_bcdadd_p(__CR6_SO, __a, __b); +} + +static __inline__ long __bcdsub_ofl(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_ppc_bcdsub_p(__CR6_SO, __a, __b); +} + +static __inline__ long __bcd_invalid(vector unsigned char __a) { + return __builtin_ppc_bcdsub_p(__CR6_SO, __a, __a); +} + +static __inline__ long __bcdcmpeq(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_ppc_bcdsub_p(__CR6_EQ, __a, __b); +} + +static __inline__ long __bcdcmplt(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_ppc_bcdsub_p(__CR6_LT, __a, __b); +} + +static __inline__ long __bcdcmpgt(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_ppc_bcdsub_p(__CR6_GT, __a, __b); +} + +static __inline__ long __bcdcmple(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_ppc_bcdsub_p(__CR6_GT_REV, __a, __b); +} + +static __inline__ long __bcdcmpge(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_ppc_bcdsub_p(__CR6_LT_REV, __a, __b); +} + +#endif // __POWER8_VECTOR__ + #undef __ATTRS_o_ai #endif /* __ALTIVEC_H */ diff --git a/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/emmintrin.h b/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/emmintrin.h index 4dcb8485e2e9..82a71788b27a 100644 --- a/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/emmintrin.h +++ b/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/emmintrin.h @@ -35,7 +35,7 @@ #ifndef EMMINTRIN_H_ #define EMMINTRIN_H_ -#if defined(__linux__) && defined(__ppc64__) +#if defined(__ppc64__) && (defined(__linux__) || defined(__FreeBSD__)) #include @@ -2319,6 +2319,7 @@ _mm_castsi128_pd(__m128i __A) #else #include_next -#endif /* defined(__linux__) && defined(__ppc64__) */ +#endif /* defined(__ppc64__) && (defined(__linux__) || defined(__FreeBSD__)) \ + */ #endif /* EMMINTRIN_H_ */ diff --git a/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/mm_malloc.h b/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/mm_malloc.h index 24b14c8e07c0..86cf1a0f7618 100644 --- a/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/mm_malloc.h +++ b/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/mm_malloc.h @@ -10,7 +10,7 @@ #ifndef _MM_MALLOC_H_INCLUDED #define _MM_MALLOC_H_INCLUDED -#if defined(__linux__) && defined(__ppc64__) +#if defined(__ppc64__) && (defined(__linux__) || defined(__FreeBSD__)) #include diff --git a/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/mmintrin.h b/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/mmintrin.h index c55c44726f00..54e4ee9f4468 100644 --- a/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/mmintrin.h +++ b/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/mmintrin.h @@ -35,7 +35,7 @@ #ifndef _MMINTRIN_H_INCLUDED #define _MMINTRIN_H_INCLUDED -#if defined(__linux__) && defined(__ppc64__) +#if defined(__ppc64__) && (defined(__linux__) || defined(__FreeBSD__)) #include /* The Intel API is flexible enough that we must allow aliasing with other @@ -1445,6 +1445,7 @@ extern __inline __m64 #else #include_next -#endif /* defined(__linux__) && defined(__ppc64__) */ +#endif /* defined(__ppc64__) && (defined(__linux__) || defined(__FreeBSD__)) \ + */ #endif /* _MMINTRIN_H_INCLUDED */ diff --git a/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/pmmintrin.h b/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/pmmintrin.h index 6d93383d5412..8d4046bd43f1 100644 --- a/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/pmmintrin.h +++ b/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/pmmintrin.h @@ -38,7 +38,7 @@ #ifndef PMMINTRIN_H_ #define PMMINTRIN_H_ -#if defined(__linux__) && defined(__ppc64__) +#if defined(__ppc64__) && (defined(__linux__) || defined(__FreeBSD__)) /* We need definitions from the SSE2 and SSE header files*/ #include @@ -145,6 +145,7 @@ _mm_lddqu_si128 (__m128i const *__P) #else #include_next -#endif /* defined(__linux__) && defined(__ppc64__) */ +#endif /* defined(__ppc64__) && (defined(__linux__) || defined(__FreeBSD__)) \ + */ #endif /* PMMINTRIN_H_ */ diff --git a/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/smmintrin.h b/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/smmintrin.h index f41264b27584..674703245a69 100644 --- a/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/smmintrin.h +++ b/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/smmintrin.h @@ -29,7 +29,7 @@ #ifndef SMMINTRIN_H_ #define SMMINTRIN_H_ -#if defined(__linux__) && defined(__ppc64__) +#if defined(__ppc64__) && (defined(__linux__) || defined(__FreeBSD__)) #include #include @@ -104,6 +104,7 @@ extern __inline __m128i #else #include_next -#endif /* defined(__linux__) && defined(__ppc64__) */ +#endif /* defined(__ppc64__) && (defined(__linux__) || defined(__FreeBSD__)) \ + */ #endif /* _SMMINTRIN_H_ */ diff --git a/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/tmmintrin.h b/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/tmmintrin.h index b5a935d5e47e..ebef7b8192d7 100644 --- a/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/tmmintrin.h +++ b/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/tmmintrin.h @@ -25,7 +25,7 @@ #ifndef TMMINTRIN_H_ #define TMMINTRIN_H_ -#if defined(__linux__) && defined(__ppc64__) +#if defined(__ppc64__) && (defined(__linux__) || defined(__FreeBSD__)) #include @@ -490,6 +490,7 @@ _mm_mulhrs_pi16 (__m64 __A, __m64 __B) #else #include_next -#endif /* defined(__linux__) && defined(__ppc64__) */ +#endif /* defined(__ppc64__) && (defined(__linux__) || defined(__FreeBSD__)) \ + */ #endif /* TMMINTRIN_H_ */ diff --git a/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/xmmintrin.h b/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/xmmintrin.h index 0e45b96769f8..956603d36408 100644 --- a/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/xmmintrin.h +++ b/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/xmmintrin.h @@ -34,7 +34,7 @@ #ifndef _XMMINTRIN_H_INCLUDED #define _XMMINTRIN_H_INCLUDED -#if defined(__linux__) && defined(__ppc64__) +#if defined(__ppc64__) && (defined(__linux__) || defined(__FreeBSD__)) /* Define four value permute mask */ #define _MM_SHUFFLE(w,x,y,z) (((w) << 6) | ((x) << 4) | ((y) << 2) | (z)) @@ -1838,6 +1838,7 @@ do { \ #else #include_next -#endif /* defined(__linux__) && defined(__ppc64__) */ +#endif /* defined(__ppc64__) && (defined(__linux__) || defined(__FreeBSD__)) \ + */ #endif /* _XMMINTRIN_H_INCLUDED */ diff --git a/contrib/llvm-project/clang/lib/Headers/stdatomic.h b/contrib/llvm-project/clang/lib/Headers/stdatomic.h index 665551ea69a4..1e47bcb2bacf 100644 --- a/contrib/llvm-project/clang/lib/Headers/stdatomic.h +++ b/contrib/llvm-project/clang/lib/Headers/stdatomic.h @@ -12,8 +12,12 @@ /* If we're hosted, fall back to the system's stdatomic.h. FreeBSD, for * example, already has a Clang-compatible stdatomic.h header. + * + * Exclude the MSVC path as well as the MSVC header as of the 14.31.30818 + * explicitly disallows `stdatomic.h` in the C mode via an `#error`. Fallback + * to the clang resource header until that is fully supported. */ -#if __STDC_HOSTED__ && __has_include_next() +#if __STDC_HOSTED__ && __has_include_next() && !defined(_MSC_VER) # include_next #else diff --git a/contrib/llvm-project/clang/lib/Parse/ParseDecl.cpp b/contrib/llvm-project/clang/lib/Parse/ParseDecl.cpp index a0871062395e..1bdeccc4cbf5 100644 --- a/contrib/llvm-project/clang/lib/Parse/ParseDecl.cpp +++ b/contrib/llvm-project/clang/lib/Parse/ParseDecl.cpp @@ -6978,13 +6978,13 @@ void Parser::ParseParameterDeclarationClause( // // We care about case 1) where the declarator type should be known, and // the identifier should be null. - if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName()) { - if (Tok.getIdentifierInfo() && - Tok.getIdentifierInfo()->isKeyword(getLangOpts())) { - Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok); - // Consume the keyword. - ConsumeToken(); - } + if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() && + Tok.isNot(tok::raw_identifier) && !Tok.isAnnotation() && + Tok.getIdentifierInfo() && + Tok.getIdentifierInfo()->isKeyword(getLangOpts())) { + Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok); + // Consume the keyword. + ConsumeToken(); } // Inform the actions module about the parameter declarator, so it gets // added to the current scope. diff --git a/contrib/llvm-project/clang/lib/Parse/ParseStmt.cpp b/contrib/llvm-project/clang/lib/Parse/ParseStmt.cpp index bb8718671bb0..292ab03e8614 100644 --- a/contrib/llvm-project/clang/lib/Parse/ParseStmt.cpp +++ b/contrib/llvm-project/clang/lib/Parse/ParseStmt.cpp @@ -2108,6 +2108,9 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { CoawaitLoc = SourceLocation(); } + if (CoawaitLoc.isValid() && getLangOpts().CPlusPlus20) + Diag(CoawaitLoc, diag::warn_deprecated_for_co_await); + // We need to perform most of the semantic analysis for a C++0x for-range // statememt before parsing the body, in order to be able to deduce the type // of an auto-typed loop variable. diff --git a/contrib/llvm-project/clang/lib/Sema/AnalysisBasedWarnings.cpp b/contrib/llvm-project/clang/lib/Sema/AnalysisBasedWarnings.cpp index 8544a4fccf4c..b4dcc9759b99 100644 --- a/contrib/llvm-project/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/contrib/llvm-project/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -464,7 +464,7 @@ static ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) { // No more CFGElements in the block? if (ri == re) { const Stmt *Term = B.getTerminatorStmt(); - if (Term && isa(Term)) { + if (Term && (isa(Term) || isa(Term))) { HasAbnormalEdge = true; continue; } diff --git a/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp b/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp index a0f6702a5f82..33e2b3b5027d 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp @@ -5297,6 +5297,7 @@ static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op) { case AtomicExpr::AO__c11_atomic_load: case AtomicExpr::AO__opencl_atomic_load: + case AtomicExpr::AO__hip_atomic_load: case AtomicExpr::AO__atomic_load_n: case AtomicExpr::AO__atomic_load: return OrderingCABI != llvm::AtomicOrderingCABI::release && @@ -5304,6 +5305,7 @@ static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op) { case AtomicExpr::AO__c11_atomic_store: case AtomicExpr::AO__opencl_atomic_store: + case AtomicExpr::AO__hip_atomic_store: case AtomicExpr::AO__atomic_store: case AtomicExpr::AO__atomic_store_n: return OrderingCABI != llvm::AtomicOrderingCABI::consume && @@ -5380,6 +5382,8 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, "need to update code for modified C11 atomics"); bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_init && Op <= AtomicExpr::AO__opencl_atomic_fetch_max; + bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_load && + Op <= AtomicExpr::AO__hip_atomic_fetch_max; bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_init && Op <= AtomicExpr::AO__c11_atomic_fetch_min) || IsOpenCL; @@ -5397,6 +5401,7 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, case AtomicExpr::AO__c11_atomic_load: case AtomicExpr::AO__opencl_atomic_load: + case AtomicExpr::AO__hip_atomic_load: case AtomicExpr::AO__atomic_load_n: Form = Load; break; @@ -5407,11 +5412,14 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, case AtomicExpr::AO__c11_atomic_store: case AtomicExpr::AO__opencl_atomic_store: + case AtomicExpr::AO__hip_atomic_store: case AtomicExpr::AO__atomic_store: case AtomicExpr::AO__atomic_store_n: Form = Copy; break; - + case AtomicExpr::AO__hip_atomic_fetch_add: + case AtomicExpr::AO__hip_atomic_fetch_min: + case AtomicExpr::AO__hip_atomic_fetch_max: case AtomicExpr::AO__c11_atomic_fetch_add: case AtomicExpr::AO__c11_atomic_fetch_sub: case AtomicExpr::AO__opencl_atomic_fetch_add: @@ -5426,6 +5434,9 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, case AtomicExpr::AO__c11_atomic_fetch_and: case AtomicExpr::AO__c11_atomic_fetch_or: case AtomicExpr::AO__c11_atomic_fetch_xor: + case AtomicExpr::AO__hip_atomic_fetch_and: + case AtomicExpr::AO__hip_atomic_fetch_or: + case AtomicExpr::AO__hip_atomic_fetch_xor: case AtomicExpr::AO__c11_atomic_fetch_nand: case AtomicExpr::AO__opencl_atomic_fetch_and: case AtomicExpr::AO__opencl_atomic_fetch_or: @@ -5452,6 +5463,7 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, break; case AtomicExpr::AO__c11_atomic_exchange: + case AtomicExpr::AO__hip_atomic_exchange: case AtomicExpr::AO__opencl_atomic_exchange: case AtomicExpr::AO__atomic_exchange_n: Form = Xchg; @@ -5463,8 +5475,10 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, case AtomicExpr::AO__c11_atomic_compare_exchange_strong: case AtomicExpr::AO__c11_atomic_compare_exchange_weak: + case AtomicExpr::AO__hip_atomic_compare_exchange_strong: case AtomicExpr::AO__opencl_atomic_compare_exchange_strong: case AtomicExpr::AO__opencl_atomic_compare_exchange_weak: + case AtomicExpr::AO__hip_atomic_compare_exchange_weak: Form = C11CmpXchg; break; @@ -5475,7 +5489,7 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, } unsigned AdjustedNumArgs = NumArgs[Form]; - if (IsOpenCL && Op != AtomicExpr::AO__opencl_atomic_init) + if ((IsOpenCL || IsHIP) && Op != AtomicExpr::AO__opencl_atomic_init) ++AdjustedNumArgs; // Check we have the right number of arguments. if (Args.size() < AdjustedNumArgs) { @@ -5532,8 +5546,8 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, // For an arithmetic operation, the implied arithmetic must be well-formed. if (Form == Arithmetic) { - // GCC does not enforce these rules for GNU atomics, but we do, because if - // we didn't it would be very confusing. FIXME: For whom? How so? + // GCC does not enforce these rules for GNU atomics, but we do to help catch + // trivial type errors. auto IsAllowedValueType = [&](QualType ValType) { if (ValType->isIntegerType()) return true; @@ -5574,8 +5588,9 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, if (!IsC11 && !AtomTy.isTriviallyCopyableType(Context) && !AtomTy->isScalarType()) { // For GNU atomics, require a trivially-copyable type. This is not part of - // the GNU atomics specification, but we enforce it, because if we didn't it - // would be very confusing. FIXME: For whom? How so? + // the GNU atomics specification but we enforce it for consistency with + // other atomics which generally all require a trivially-copyable type. This + // is because atomics just copy bits. Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_trivial_copy) << Ptr->getType() << Ptr->getSourceRange(); return ExprError(); @@ -5614,7 +5629,7 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, // arguments are actually passed as pointers. QualType ByValType = ValType; // 'CP' bool IsPassedByAddress = false; - if (!IsC11 && !IsN) { + if (!IsC11 && !IsHIP && !IsN) { ByValType = Ptr->getType(); IsPassedByAddress = true; } @@ -5793,11 +5808,14 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, if ((Op == AtomicExpr::AO__c11_atomic_load || Op == AtomicExpr::AO__c11_atomic_store || Op == AtomicExpr::AO__opencl_atomic_load || - Op == AtomicExpr::AO__opencl_atomic_store ) && + Op == AtomicExpr::AO__hip_atomic_load || + Op == AtomicExpr::AO__opencl_atomic_store || + Op == AtomicExpr::AO__hip_atomic_store) && Context.AtomicUsesUnsupportedLibcall(AE)) Diag(AE->getBeginLoc(), diag::err_atomic_load_store_uses_lib) << ((Op == AtomicExpr::AO__c11_atomic_load || - Op == AtomicExpr::AO__opencl_atomic_load) + Op == AtomicExpr::AO__opencl_atomic_load || + Op == AtomicExpr::AO__hip_atomic_load) ? 0 : 1); diff --git a/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp b/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp index af174ac1ca1a..7be71ca49ea2 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp @@ -10268,13 +10268,9 @@ static bool checkNonMultiVersionCompatAttributes(Sema &S, const FunctionDecl *FD, const FunctionDecl *CausedFD, MultiVersionKind MVType) { - bool IsCPUSpecificCPUDispatchMVType = - MVType == MultiVersionKind::CPUDispatch || - MVType == MultiVersionKind::CPUSpecific; - const auto Diagnose = [FD, CausedFD, IsCPUSpecificCPUDispatchMVType]( - Sema &S, const Attr *A) { + const auto Diagnose = [FD, CausedFD, MVType](Sema &S, const Attr *A) { S.Diag(FD->getLocation(), diag::err_multiversion_disallowed_other_attr) - << IsCPUSpecificCPUDispatchMVType << A; + << static_cast(MVType) << A; if (CausedFD) S.Diag(CausedFD->getLocation(), diag::note_multiversioning_caused_here); return true; @@ -10292,6 +10288,10 @@ static bool checkNonMultiVersionCompatAttributes(Sema &S, if (MVType != MultiVersionKind::Target) return Diagnose(S, A); break; + case attr::TargetClones: + if (MVType != MultiVersionKind::TargetClones) + return Diagnose(S, A); + break; default: if (!AttrCompatibleWithMultiVersion(A->getKind(), MVType)) return Diagnose(S, A); @@ -10318,6 +10318,7 @@ bool Sema::areMultiversionVariantFunctionsCompatible( DefaultedFuncs = 6, ConstexprFuncs = 7, ConstevalFuncs = 8, + Lambda = 9, }; enum Different { CallingConv = 0, @@ -10445,7 +10446,7 @@ static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD, S.PDiag(diag::note_multiversioning_caused_here)), PartialDiagnosticAt(NewFD->getLocation(), S.PDiag(diag::err_multiversion_doesnt_support) - << IsCPUSpecificCPUDispatchMVType), + << static_cast(MVType)), PartialDiagnosticAt(NewFD->getLocation(), S.PDiag(diag::err_multiversion_diff)), /*TemplatesSupported=*/false, @@ -10574,21 +10575,30 @@ static bool CheckTargetCausesMultiVersioning( return false; } +static bool MultiVersionTypesCompatible(MultiVersionKind Old, + MultiVersionKind New) { + if (Old == New || Old == MultiVersionKind::None || + New == MultiVersionKind::None) + return true; + + return (Old == MultiVersionKind::CPUDispatch && + New == MultiVersionKind::CPUSpecific) || + (Old == MultiVersionKind::CPUSpecific && + New == MultiVersionKind::CPUDispatch); +} + /// Check the validity of a new function declaration being added to an existing /// multiversioned declaration collection. static bool CheckMultiVersionAdditionalDecl( Sema &S, FunctionDecl *OldFD, FunctionDecl *NewFD, MultiVersionKind NewMVType, const TargetAttr *NewTA, const CPUDispatchAttr *NewCPUDisp, const CPUSpecificAttr *NewCPUSpec, - bool &Redeclaration, NamedDecl *&OldDecl, bool &MergeTypeWithPrevious, - LookupResult &Previous) { + const TargetClonesAttr *NewClones, bool &Redeclaration, NamedDecl *&OldDecl, + bool &MergeTypeWithPrevious, LookupResult &Previous) { MultiVersionKind OldMVType = OldFD->getMultiVersionKind(); // Disallow mixing of multiversioning types. - if ((OldMVType == MultiVersionKind::Target && - NewMVType != MultiVersionKind::Target) || - (NewMVType == MultiVersionKind::Target && - OldMVType != MultiVersionKind::Target)) { + if (!MultiVersionTypesCompatible(OldMVType, NewMVType)) { S.Diag(NewFD->getLocation(), diag::err_multiversion_types_mixed); S.Diag(OldFD->getLocation(), diag::note_previous_declaration); NewFD->setInvalidDecl(); @@ -10613,7 +10623,12 @@ static bool CheckMultiVersionAdditionalDecl( if (S.IsOverload(NewFD, CurFD, UseMemberUsingDeclRules)) continue; - if (NewMVType == MultiVersionKind::Target) { + switch (NewMVType) { + case MultiVersionKind::None: + assert(OldMVType == MultiVersionKind::TargetClones && + "Only target_clones can be omitted in subsequent declarations"); + break; + case MultiVersionKind::Target: { const auto *CurTA = CurFD->getAttr(); if (CurTA->getFeaturesStr() == NewTA->getFeaturesStr()) { NewFD->setIsMultiVersion(); @@ -10629,7 +10644,30 @@ static bool CheckMultiVersionAdditionalDecl( NewFD->setInvalidDecl(); return true; } - } else { + break; + } + case MultiVersionKind::TargetClones: { + const auto *CurClones = CurFD->getAttr(); + Redeclaration = true; + OldDecl = CurFD; + MergeTypeWithPrevious = true; + NewFD->setIsMultiVersion(); + + if (CurClones && NewClones && + (CurClones->featuresStrs_size() != NewClones->featuresStrs_size() || + !std::equal(CurClones->featuresStrs_begin(), + CurClones->featuresStrs_end(), + NewClones->featuresStrs_begin()))) { + S.Diag(NewFD->getLocation(), diag::err_target_clone_doesnt_match); + S.Diag(CurFD->getLocation(), diag::note_previous_declaration); + NewFD->setInvalidDecl(); + return true; + } + + return false; + } + case MultiVersionKind::CPUSpecific: + case MultiVersionKind::CPUDispatch: { const auto *CurCPUSpec = CurFD->getAttr(); const auto *CurCPUDisp = CurFD->getAttr(); // Handle CPUDispatch/CPUSpecific versions. @@ -10684,8 +10722,8 @@ static bool CheckMultiVersionAdditionalDecl( } } } - // If the two decls aren't the same MVType, there is no possible error - // condition. + break; + } } } @@ -10721,7 +10759,6 @@ static bool CheckMultiVersionAdditionalDecl( return false; } - /// Check the validity of a mulitversion function declaration. /// Also sets the multiversion'ness' of the function itself. /// @@ -10735,23 +10772,14 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, const auto *NewTA = NewFD->getAttr(); const auto *NewCPUDisp = NewFD->getAttr(); const auto *NewCPUSpec = NewFD->getAttr(); - - // Mixing Multiversioning types is prohibited. - if ((NewTA && NewCPUDisp) || (NewTA && NewCPUSpec) || - (NewCPUDisp && NewCPUSpec)) { - S.Diag(NewFD->getLocation(), diag::err_multiversion_types_mixed); - NewFD->setInvalidDecl(); - return true; - } - - MultiVersionKind MVType = NewFD->getMultiVersionKind(); + const auto *NewClones = NewFD->getAttr(); + MultiVersionKind MVType = NewFD->getMultiVersionKind(); // Main isn't allowed to become a multiversion function, however it IS // permitted to have 'main' be marked with the 'target' optimization hint. if (NewFD->isMain()) { - if ((MVType == MultiVersionKind::Target && NewTA->isDefaultVersion()) || - MVType == MultiVersionKind::CPUDispatch || - MVType == MultiVersionKind::CPUSpecific) { + if (MVType != MultiVersionKind::None && + !(MVType == MultiVersionKind::Target && !NewTA->isDefaultVersion())) { S.Diag(NewFD->getLocation(), diag::err_multiversion_not_allowed_on_main); NewFD->setInvalidDecl(); return true; @@ -10774,13 +10802,35 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, if (!OldFD->isMultiVersion() && MVType == MultiVersionKind::None) return false; - if (OldFD->isMultiVersion() && MVType == MultiVersionKind::None) { + // Multiversioned redeclarations aren't allowed to omit the attribute, except + // for target_clones. + if (OldFD->isMultiVersion() && MVType == MultiVersionKind::None && + OldFD->getMultiVersionKind() != MultiVersionKind::TargetClones) { S.Diag(NewFD->getLocation(), diag::err_multiversion_required_in_redecl) << (OldFD->getMultiVersionKind() != MultiVersionKind::Target); NewFD->setInvalidDecl(); return true; } + if (!OldFD->isMultiVersion()) { + switch (MVType) { + case MultiVersionKind::Target: + return CheckTargetCausesMultiVersioning(S, OldFD, NewFD, NewTA, + Redeclaration, OldDecl, + MergeTypeWithPrevious, Previous); + case MultiVersionKind::TargetClones: + if (OldFD->isUsed(false)) { + NewFD->setInvalidDecl(); + return S.Diag(NewFD->getLocation(), diag::err_multiversion_after_used); + } + OldFD->setIsMultiVersion(); + break; + case MultiVersionKind::CPUDispatch: + case MultiVersionKind::CPUSpecific: + case MultiVersionKind::None: + break; + } + } // Handle the target potentially causes multiversioning case. if (!OldFD->isMultiVersion() && MVType == MultiVersionKind::Target) return CheckTargetCausesMultiVersioning(S, OldFD, NewFD, NewTA, @@ -10791,8 +10841,8 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, // appropriate attribute in the current function decl. Resolve that these are // still compatible with previous declarations. return CheckMultiVersionAdditionalDecl( - S, OldFD, NewFD, MVType, NewTA, NewCPUDisp, NewCPUSpec, Redeclaration, - OldDecl, MergeTypeWithPrevious, Previous); + S, OldFD, NewFD, MVType, NewTA, NewCPUDisp, NewCPUSpec, NewClones, + Redeclaration, OldDecl, MergeTypeWithPrevious, Previous); } /// Perform semantic checking of a new function declaration. diff --git a/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp b/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp index ef889a36bd55..4df8687aff89 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp @@ -1965,6 +1965,28 @@ static void handleRestrictAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + // Ensure we don't combine these with themselves, since that causes some + // confusing behavior. + if (AL.getParsedKind() == ParsedAttr::AT_CPUDispatch) { + if (checkAttrMutualExclusion(S, D, AL)) + return; + + if (const auto *Other = D->getAttr()) { + S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL; + S.Diag(Other->getLocation(), diag::note_conflicting_attribute); + return; + } + } else if (AL.getParsedKind() == ParsedAttr::AT_CPUSpecific) { + if (checkAttrMutualExclusion(S, D, AL)) + return; + + if (const auto *Other = D->getAttr()) { + S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL; + S.Diag(Other->getLocation(), diag::note_conflicting_attribute); + return; + } + } + FunctionDecl *FD = cast(D); if (const auto *MD = dyn_cast(D)) { @@ -3211,54 +3233,57 @@ static void handleCodeSegAttr(Sema &S, Decl *D, const ParsedAttr &AL) { bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) { enum FirstParam { Unsupported, Duplicate, Unknown }; enum SecondParam { None, Architecture, Tune }; + enum ThirdParam { Target, TargetClones }; if (AttrStr.contains("fpmath=")) return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) - << Unsupported << None << "fpmath="; + << Unsupported << None << "fpmath=" << Target; // Diagnose use of tune if target doesn't support it. if (!Context.getTargetInfo().supportsTargetAttributeTune() && AttrStr.contains("tune=")) return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) - << Unsupported << None << "tune="; + << Unsupported << None << "tune=" << Target; ParsedTargetAttr ParsedAttrs = TargetAttr::parse(AttrStr); if (!ParsedAttrs.Architecture.empty() && !Context.getTargetInfo().isValidCPUName(ParsedAttrs.Architecture)) return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) - << Unknown << Architecture << ParsedAttrs.Architecture; + << Unknown << Architecture << ParsedAttrs.Architecture << Target; if (!ParsedAttrs.Tune.empty() && !Context.getTargetInfo().isValidCPUName(ParsedAttrs.Tune)) return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) - << Unknown << Tune << ParsedAttrs.Tune; + << Unknown << Tune << ParsedAttrs.Tune << Target; if (ParsedAttrs.DuplicateArchitecture) return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) - << Duplicate << None << "arch="; + << Duplicate << None << "arch=" << Target; if (ParsedAttrs.DuplicateTune) return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) - << Duplicate << None << "tune="; + << Duplicate << None << "tune=" << Target; for (const auto &Feature : ParsedAttrs.Features) { auto CurFeature = StringRef(Feature).drop_front(); // remove + or -. if (!Context.getTargetInfo().isValidFeatureName(CurFeature)) return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) - << Unsupported << None << CurFeature; + << Unsupported << None << CurFeature << Target; } TargetInfo::BranchProtectionInfo BPI; - StringRef Error; - if (!ParsedAttrs.BranchProtection.empty() && - !Context.getTargetInfo().validateBranchProtection( - ParsedAttrs.BranchProtection, BPI, Error)) { - if (Error.empty()) + StringRef DiagMsg; + if (ParsedAttrs.BranchProtection.empty()) + return false; + if (!Context.getTargetInfo().validateBranchProtection( + ParsedAttrs.BranchProtection, BPI, DiagMsg)) { + if (DiagMsg.empty()) return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) - << Unsupported << None << "branch-protection"; - else - return Diag(LiteralLoc, diag::err_invalid_branch_protection_spec) - << Error; + << Unsupported << None << "branch-protection" << Target; + return Diag(LiteralLoc, diag::err_invalid_branch_protection_spec) + << DiagMsg; } + if (!DiagMsg.empty()) + Diag(LiteralLoc, diag::warn_unsupported_branch_protection_spec) << DiagMsg; return false; } @@ -3274,6 +3299,107 @@ static void handleTargetAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +bool Sema::checkTargetClonesAttrString(SourceLocation LiteralLoc, StringRef Str, + const StringLiteral *Literal, + bool &HasDefault, bool &HasCommas, + SmallVectorImpl &Strings) { + enum FirstParam { Unsupported, Duplicate, Unknown }; + enum SecondParam { None, Architecture, Tune }; + enum ThirdParam { Target, TargetClones }; + HasCommas = HasCommas || Str.contains(','); + // Warn on empty at the beginning of a string. + if (Str.size() == 0) + return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) + << Unsupported << None << "" << TargetClones; + + std::pair Parts = {{}, Str}; + while (!Parts.second.empty()) { + Parts = Parts.second.split(','); + StringRef Cur = Parts.first.trim(); + SourceLocation CurLoc = Literal->getLocationOfByte( + Cur.data() - Literal->getString().data(), getSourceManager(), + getLangOpts(), Context.getTargetInfo()); + + bool DefaultIsDupe = false; + if (Cur.empty()) + return Diag(CurLoc, diag::warn_unsupported_target_attribute) + << Unsupported << None << "" << TargetClones; + + if (Cur.startswith("arch=")) { + if (!Context.getTargetInfo().isValidCPUName( + Cur.drop_front(sizeof("arch=") - 1))) + return Diag(CurLoc, diag::warn_unsupported_target_attribute) + << Unsupported << Architecture + << Cur.drop_front(sizeof("arch=") - 1) << TargetClones; + } else if (Cur == "default") { + DefaultIsDupe = HasDefault; + HasDefault = true; + } else if (!Context.getTargetInfo().isValidFeatureName(Cur)) + return Diag(CurLoc, diag::warn_unsupported_target_attribute) + << Unsupported << None << Cur << TargetClones; + + if (llvm::find(Strings, Cur) != Strings.end() || DefaultIsDupe) + Diag(CurLoc, diag::warn_target_clone_duplicate_options); + // Note: Add even if there are duplicates, since it changes name mangling. + Strings.push_back(Cur); + } + + if (Str.rtrim().endswith(",")) + return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) + << Unsupported << None << "" << TargetClones; + return false; +} + +static void handleTargetClonesAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + // Ensure we don't combine these with themselves, since that causes some + // confusing behavior. + if (const auto *Other = D->getAttr()) { + S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL; + S.Diag(Other->getLocation(), diag::note_conflicting_attribute); + return; + } + if (checkAttrMutualExclusion(S, D, AL)) + return; + + SmallVector Strings; + bool HasCommas = false, HasDefault = false; + + for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) { + StringRef CurStr; + SourceLocation LiteralLoc; + if (!S.checkStringLiteralArgumentAttr(AL, I, CurStr, &LiteralLoc) || + S.checkTargetClonesAttrString( + LiteralLoc, CurStr, + cast(AL.getArgAsExpr(I)->IgnoreParenCasts()), + HasDefault, HasCommas, Strings)) + return; + } + + if (HasCommas && AL.getNumArgs() > 1) + S.Diag(AL.getLoc(), diag::warn_target_clone_mixed_values); + + if (!HasDefault) { + S.Diag(AL.getLoc(), diag::err_target_clone_must_have_default); + return; + } + + // FIXME: We could probably figure out how to get this to work for lambdas + // someday. + if (const auto *MD = dyn_cast(D)) { + if (MD->getParent()->isLambda()) { + S.Diag(D->getLocation(), diag::err_multiversion_doesnt_support) + << static_cast(MultiVersionKind::TargetClones) + << /*Lambda*/ 9; + return; + } + } + + cast(D)->setIsMultiVersion(); + TargetClonesAttr *NewAttr = ::new (S.Context) + TargetClonesAttr(S.Context, AL, Strings.data(), Strings.size()); + D->addAttr(NewAttr); +} + static void handleMinVectorWidthAttr(Sema &S, Decl *D, const ParsedAttr &AL) { Expr *E = AL.getArgAsExpr(0); uint32_t VecWidth; @@ -8217,6 +8343,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case ParsedAttr::AT_Target: handleTargetAttr(S, D, AL); break; + case ParsedAttr::AT_TargetClones: + handleTargetClonesAttr(S, D, AL); + break; case ParsedAttr::AT_MinVectorWidth: handleMinVectorWidthAttr(S, D, AL); break; diff --git a/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp index 8592335e20d3..b305d4e5b92f 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp @@ -16566,6 +16566,17 @@ Sema::PushExpressionEvaluationContext( ExpressionEvaluationContextRecord::ExpressionKind ExprContext) { ExprEvalContexts.emplace_back(NewContext, ExprCleanupObjects.size(), Cleanup, LambdaContextDecl, ExprContext); + + // Discarded statements and immediate contexts nested in other + // discarded statements or immediate context are themselves + // a discarded statement or an immediate context, respectively. + ExprEvalContexts.back().InDiscardedStatement = + ExprEvalContexts[ExprEvalContexts.size() - 2] + .isDiscardedStatementContext(); + ExprEvalContexts.back().InImmediateFunctionContext = + ExprEvalContexts[ExprEvalContexts.size() - 2] + .isImmediateFunctionContext(); + Cleanup.reset(); if (!MaybeODRUseExprs.empty()) std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs); @@ -18965,6 +18976,10 @@ bool Sema::DiagIfReachable(SourceLocation Loc, ArrayRef Stmts, /// during overload resolution or within sizeof/alignof/typeof/typeid. bool Sema::DiagRuntimeBehavior(SourceLocation Loc, ArrayRef Stmts, const PartialDiagnostic &PD) { + + if (ExprEvalContexts.back().isDiscardedStatementContext()) + return false; + switch (ExprEvalContexts.back().Context) { case ExpressionEvaluationContext::Unevaluated: case ExpressionEvaluationContext::UnevaluatedList: diff --git a/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp index 635252584562..d25f329f85e4 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp @@ -1508,8 +1508,9 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, } // Only construct objects with object types. - // There doesn't seem to be an explicit rule for this but functions are - // not objects, so they cannot take initializers. + // The standard doesn't explicitly forbid function types here, but that's an + // obvious oversight, as there's no way to dynamically construct a function + // in general. if (Ty->isFunctionType()) return ExprError(Diag(TyBeginLoc, diag::err_init_for_function_type) << Ty << FullRange); diff --git a/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp b/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp index 3c820829864d..1d90759f2406 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp @@ -3563,8 +3563,7 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, bool HasDeducedReturnType = CurLambda && hasDeducedReturnType(CurLambda->CallOperator); - if (ExprEvalContexts.back().Context == - ExpressionEvaluationContext::DiscardedStatement && + if (ExprEvalContexts.back().isDiscardedStatementContext() && (HasDeducedReturnType || CurCap->HasImplicitReturnType)) { if (RetValExp) { ExprResult ER = @@ -3880,8 +3879,7 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, if (RetVal.isInvalid()) return StmtError(); StmtResult R = BuildReturnStmt(ReturnLoc, RetVal.get()); - if (R.isInvalid() || ExprEvalContexts.back().Context == - ExpressionEvaluationContext::DiscardedStatement) + if (R.isInvalid() || ExprEvalContexts.back().isDiscardedStatementContext()) return R; if (VarDecl *VD = @@ -3966,8 +3964,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { // C++1z: discarded return statements are not considered when deducing a // return type. - if (ExprEvalContexts.back().Context == - ExpressionEvaluationContext::DiscardedStatement && + if (ExprEvalContexts.back().isDiscardedStatementContext() && FnRetType->getContainedAutoType()) { if (RetValExp) { ExprResult ER = diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp index bc939d252800..d57bab154b61 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -686,8 +686,8 @@ SwitchNodeBuilder::generateDefaultCaseNode(ProgramStateRef St, assert(Src->succ_rbegin() != Src->succ_rend()); CFGBlock *DefaultBlock = *Src->succ_rbegin(); - // Sanity check for default blocks that are unreachable and not caught - // by earlier stages. + // Basic correctness check for default blocks that are unreachable and not + // caught by earlier stages. if (!DefaultBlock) return nullptr; diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp index 74403a160b8e..23c67c64f975 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp +++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp @@ -2191,6 +2191,42 @@ LLVM_NODISCARD ProgramStateRef reAssume(ProgramStateRef State, Constraint->getMaxValue(), true); } +// Simplify the given symbol with the help of the SValBuilder. In +// SValBuilder::symplifySval, we traverse the symbol tree and query the +// constraint values for the sub-trees and if a value is a constant we do the +// constant folding. Compound symbols might collapse to simpler symbol tree +// that is still possible to further simplify. Thus, we do the simplification on +// a new symbol tree until we reach the simplest form, i.e. the fixpoint. +// +// Consider the following symbol `(b * b) * b * b` which has this tree: +// * +// / \ +// * b +// / \ +// / b +// (b * b) +// Now, if the `b * b == 1` new constraint is added then during the first +// iteration we have the following transformations: +// * * +// / \ / \ +// * b --> b b +// / \ +// / b +// 1 +// We need another iteration to reach the final result `1`. +LLVM_NODISCARD +static SVal simplifyUntilFixpoint(SValBuilder &SVB, ProgramStateRef State, + const SymbolRef Sym) { + SVal Val = SVB.makeSymbolVal(Sym); + SVal SimplifiedVal = SVB.simplifySVal(State, Val); + // Do the simplification until we can. + while (SimplifiedVal != Val) { + Val = SimplifiedVal; + SimplifiedVal = SVB.simplifySVal(State, Val); + } + return SimplifiedVal; +} + // Iterate over all symbols and try to simplify them. Once a symbol is // simplified then we check if we can merge the simplified symbol's equivalence // class to this class. This way, we simplify not just the symbols but the @@ -2202,7 +2238,8 @@ EquivalenceClass::simplify(SValBuilder &SVB, RangeSet::Factory &F, SymbolSet ClassMembers = Class.getClassMembers(State); for (const SymbolRef &MemberSym : ClassMembers) { - const SVal SimplifiedMemberVal = simplifyToSVal(State, MemberSym); + const SVal SimplifiedMemberVal = + simplifyUntilFixpoint(SVB, State, MemberSym); const SymbolRef SimplifiedMemberSym = SimplifiedMemberVal.getAsSymbol(); // The symbol is collapsed to a constant, check if the current State is diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 681a1f64eadc..4ca35dd06ae5 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -372,6 +372,15 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state, NonLoc InputLHS = lhs; NonLoc InputRHS = rhs; + // Constraints may have changed since the creation of a bound SVal. Check if + // the values can be simplified based on those new constraints. + SVal simplifiedLhs = simplifySVal(state, lhs); + SVal simplifiedRhs = simplifySVal(state, rhs); + if (auto simplifiedLhsAsNonLoc = simplifiedLhs.getAs()) + lhs = *simplifiedLhsAsNonLoc; + if (auto simplifiedRhsAsNonLoc = simplifiedRhs.getAs()) + rhs = *simplifiedRhsAsNonLoc; + // Handle trivial case where left-side and right-side are the same. if (lhs == rhs) switch (op) { @@ -619,16 +628,6 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state, } } - // Does the symbolic expression simplify to a constant? - // If so, "fold" the constant by setting 'lhs' to a ConcreteInt - // and try again. - SVal simplifiedLhs = simplifySVal(state, lhs); - if (simplifiedLhs != lhs) - if (auto simplifiedLhsAsNonLoc = simplifiedLhs.getAs()) { - lhs = *simplifiedLhsAsNonLoc; - continue; - } - // Is the RHS a constant? if (const llvm::APSInt *RHSValue = getKnownValue(state, rhs)) return MakeSymIntVal(Sym, op, *RHSValue, resultTy); @@ -1103,7 +1102,6 @@ const llvm::APSInt *SimpleSValBuilder::getKnownValue(ProgramStateRef state, if (SymbolRef Sym = V.getAsSymbol()) return state->getConstraintManager().getSymVal(state, Sym); - // FIXME: Add support for SymExprs. return nullptr; } @@ -1135,6 +1133,24 @@ SVal SimpleSValBuilder::simplifySVal(ProgramStateRef State, SVal V) { return cache(Sym, SVB.makeSymbolVal(Sym)); } + // Return the known const value for the Sym if available, or return Undef + // otherwise. + SVal getConst(SymbolRef Sym) { + const llvm::APSInt *Const = + State->getConstraintManager().getSymVal(State, Sym); + if (Const) + return Loc::isLocType(Sym->getType()) ? (SVal)SVB.makeIntLocVal(*Const) + : (SVal)SVB.makeIntVal(*Const); + return UndefinedVal(); + } + + SVal getConstOrVisit(SymbolRef Sym) { + const SVal Ret = getConst(Sym); + if (Ret.isUndef()) + return Visit(Sym); + return Ret; + } + public: Simplifier(ProgramStateRef State) : State(State), SVB(State->getStateManager().getSValBuilder()) {} @@ -1148,15 +1164,14 @@ SVal SimpleSValBuilder::simplifySVal(ProgramStateRef State, SVal V) { return SVB.makeSymbolVal(S); } - // TODO: Support SymbolCast. Support IntSymExpr when/if we actually - // start producing them. + // TODO: Support SymbolCast. SVal VisitSymIntExpr(const SymIntExpr *S) { auto I = Cached.find(S); if (I != Cached.end()) return I->second; - SVal LHS = Visit(S->getLHS()); + SVal LHS = getConstOrVisit(S->getLHS()); if (isUnchanged(S->getLHS(), LHS)) return skip(S); @@ -1183,6 +1198,20 @@ SVal SimpleSValBuilder::simplifySVal(ProgramStateRef State, SVal V) { S, SVB.evalBinOp(State, S->getOpcode(), LHS, RHS, S->getType())); } + SVal VisitIntSymExpr(const IntSymExpr *S) { + auto I = Cached.find(S); + if (I != Cached.end()) + return I->second; + + SVal RHS = getConstOrVisit(S->getRHS()); + if (isUnchanged(S->getRHS(), RHS)) + return skip(S); + + SVal LHS = SVB.makeIntVal(S->getLHS()); + return cache( + S, SVB.evalBinOp(State, S->getOpcode(), LHS, RHS, S->getType())); + } + SVal VisitSymSymExpr(const SymSymExpr *S) { auto I = Cached.find(S); if (I != Cached.end()) @@ -1196,8 +1225,9 @@ SVal SimpleSValBuilder::simplifySVal(ProgramStateRef State, SVal V) { Loc::isLocType(S->getRHS()->getType())) return skip(S); - SVal LHS = Visit(S->getLHS()); - SVal RHS = Visit(S->getRHS()); + SVal LHS = getConstOrVisit(S->getLHS()); + SVal RHS = getConstOrVisit(S->getRHS()); + if (isUnchanged(S->getLHS(), LHS) && isUnchanged(S->getRHS(), RHS)) return skip(S); diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index 31de49033ac2..f692c68045ee 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -591,16 +591,24 @@ AnalysisConsumer::getModeForDecl(Decl *D, AnalysisMode Mode) { // - Main source file: run both path-sensitive and non-path-sensitive checks. // - Header files: run non-path-sensitive checks only. // - System headers: don't run any checks. - SourceManager &SM = Ctx->getSourceManager(); - const Stmt *Body = D->getBody(); - SourceLocation SL = Body ? Body->getBeginLoc() : D->getLocation(); - SL = SM.getExpansionLoc(SL); + if (Opts->AnalyzeAll) + return Mode; - if (!Opts->AnalyzeAll && !Mgr->isInCodeFile(SL)) { - if (SL.isInvalid() || SM.isInSystemHeader(SL)) - return AM_None; + const SourceManager &SM = Ctx->getSourceManager(); + + const SourceLocation Loc = [&SM](Decl *D) -> SourceLocation { + const Stmt *Body = D->getBody(); + SourceLocation SL = Body ? Body->getBeginLoc() : D->getLocation(); + return SM.getExpansionLoc(SL); + }(D); + + // Ignore system headers. + if (Loc.isInvalid() || SM.isInSystemHeader(Loc)) + return AM_None; + + // Disable path sensitive analysis in user-headers. + if (!Mgr->isInCodeFile(Loc)) return Mode & ~AM_Path; - } return Mode; } diff --git a/contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp b/contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp index 40e8bd2b8776..f7c711690d7e 100644 --- a/contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp +++ b/contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp @@ -129,7 +129,7 @@ DependencyScanningFilesystemSharedCache::get(StringRef Key, bool Minimized) { /// /// This is kinda hacky, it would be better if we knew what kind of file Clang /// was expecting instead. -static bool shouldMinimize(StringRef Filename) { +static bool shouldMinimizeBasedOnExtension(StringRef Filename) { StringRef Ext = llvm::sys::path::extension(Filename); if (Ext.empty()) return true; // C++ standard library @@ -147,26 +147,43 @@ static bool shouldCacheStatFailures(StringRef Filename) { StringRef Ext = llvm::sys::path::extension(Filename); if (Ext.empty()) return false; // This may be the module cache directory. - return shouldMinimize(Filename); // Only cache stat failures on source files. + // Only cache stat failures on source files. + return shouldMinimizeBasedOnExtension(Filename); } -void DependencyScanningWorkerFilesystem::ignoreFile(StringRef RawFilename) { - llvm::SmallString<256> Filename; - llvm::sys::path::native(RawFilename, Filename); - IgnoredFiles.insert(Filename); -} - -bool DependencyScanningWorkerFilesystem::shouldIgnoreFile( +void DependencyScanningWorkerFilesystem::disableMinimization( StringRef RawFilename) { llvm::SmallString<256> Filename; llvm::sys::path::native(RawFilename, Filename); - return IgnoredFiles.contains(Filename); + NotToBeMinimized.insert(Filename); +} + +bool DependencyScanningWorkerFilesystem::shouldMinimize(StringRef RawFilename) { + if (!shouldMinimizeBasedOnExtension(RawFilename)) + return false; + + llvm::SmallString<256> Filename; + llvm::sys::path::native(RawFilename, Filename); + return !NotToBeMinimized.contains(Filename); +} + +CachedFileSystemEntry DependencyScanningWorkerFilesystem::createFileSystemEntry( + llvm::ErrorOr &&MaybeStatus, StringRef Filename, + bool ShouldMinimize) { + if (!MaybeStatus) + return CachedFileSystemEntry(MaybeStatus.getError()); + + if (MaybeStatus->isDirectory()) + return CachedFileSystemEntry::createDirectoryEntry(std::move(*MaybeStatus)); + + return CachedFileSystemEntry::createFileEntry(Filename, getUnderlyingFS(), + ShouldMinimize); } llvm::ErrorOr DependencyScanningWorkerFilesystem::getOrCreateFileSystemEntry( const StringRef Filename) { - bool ShouldMinimize = !shouldIgnoreFile(Filename) && shouldMinimize(Filename); + bool ShouldMinimize = shouldMinimize(Filename); if (const auto *Entry = Cache.getCachedEntry(Filename, ShouldMinimize)) return Entry; @@ -182,23 +199,15 @@ DependencyScanningWorkerFilesystem::getOrCreateFileSystemEntry( CachedFileSystemEntry &CacheEntry = SharedCacheEntry.Value; if (!CacheEntry.isValid()) { - llvm::vfs::FileSystem &FS = getUnderlyingFS(); - auto MaybeStatus = FS.status(Filename); - if (!MaybeStatus) { - if (!shouldCacheStatFailures(Filename)) - // HACK: We need to always restat non source files if the stat fails. - // This is because Clang first looks up the module cache and module - // files before building them, and then looks for them again. If we - // cache the stat failure, it won't see them the second time. - return MaybeStatus.getError(); - else - CacheEntry = CachedFileSystemEntry(MaybeStatus.getError()); - } else if (MaybeStatus->isDirectory()) - CacheEntry = CachedFileSystemEntry::createDirectoryEntry( - std::move(*MaybeStatus)); - else - CacheEntry = CachedFileSystemEntry::createFileEntry(Filename, FS, - ShouldMinimize); + auto MaybeStatus = getUnderlyingFS().status(Filename); + if (!MaybeStatus && !shouldCacheStatFailures(Filename)) + // HACK: We need to always restat non source files if the stat fails. + // This is because Clang first looks up the module cache and module + // files before building them, and then looks for them again. If we + // cache the stat failure, it won't see them the second time. + return MaybeStatus.getError(); + CacheEntry = createFileSystemEntry(std::move(MaybeStatus), Filename, + ShouldMinimize); } Result = &CacheEntry; diff --git a/contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 7fdc49271791..70bb6c5caf87 100644 --- a/contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -193,20 +193,19 @@ class DependencyScanningAction : public tooling::ToolAction { // Use the dependency scanning optimized file system if requested to do so. if (DepFS) { - DepFS->clearIgnoredFiles(); - // Ignore any files that contributed to prebuilt modules. The implicit - // build validates the modules by comparing the reported sizes of their - // inputs to the current state of the filesystem. Minimization would throw - // this mechanism off. + DepFS->enableMinimizationOfAllFiles(); + // Don't minimize any files that contributed to prebuilt modules. The + // implicit build validates the modules by comparing the reported sizes of + // their inputs to the current state of the filesystem. Minimization would + // throw this mechanism off. for (const auto &File : PrebuiltModulesInputFiles) - DepFS->ignoreFile(File.getKey()); - // Add any filenames that were explicity passed in the build settings and - // that might be opened, as we want to ensure we don't run source - // minimization on them. + DepFS->disableMinimization(File.getKey()); + // Don't minimize any files that were explicitly passed in the build + // settings and that might be opened. for (const auto &E : ScanInstance.getHeaderSearchOpts().UserEntries) - DepFS->ignoreFile(E.Path); + DepFS->disableMinimization(E.Path); for (const auto &F : ScanInstance.getHeaderSearchOpts().VFSOverlayFiles) - DepFS->ignoreFile(F); + DepFS->disableMinimization(F); // Support for virtual file system overlays on top of the caching // filesystem. diff --git a/contrib/llvm-project/clang/utils/TableGen/ASTTableGen.cpp b/contrib/llvm-project/clang/utils/TableGen/ASTTableGen.cpp index 3f6da40964e0..6aa8b28a942f 100644 --- a/contrib/llvm-project/clang/utils/TableGen/ASTTableGen.cpp +++ b/contrib/llvm-project/clang/utils/TableGen/ASTTableGen.cpp @@ -107,7 +107,7 @@ static void visitASTNodeRecursive(ASTNode node, ASTNode base, static void visitHierarchy(RecordKeeper &records, StringRef nodeClassName, ASTNodeHierarchyVisitor visit) { - // Check for the node class, just as a sanity check. + // Check for the node class, just as a basic correctness check. if (!records.getClass(nodeClassName)) { PrintFatalError(Twine("cannot find definition for node class ") + nodeClassName); diff --git a/contrib/llvm-project/compiler-rt/include/profile/MemProfData.inc b/contrib/llvm-project/compiler-rt/include/profile/MemProfData.inc new file mode 100644 index 000000000000..d64227e4ba31 --- /dev/null +++ b/contrib/llvm-project/compiler-rt/include/profile/MemProfData.inc @@ -0,0 +1,61 @@ +#ifndef MEMPROF_DATA_INC +#define MEMPROF_DATA_INC +/*===-- MemProfData.inc - MemProf profiling runtime structures -*- 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 +|* +\*===----------------------------------------------------------------------===*/ +/* + * This is the main file that defines all the data structure, signature, + * constant literals that are shared across profiling runtime library, + * and host tools (reader/writer). + * + * This file has two identical copies. The primary copy lives in LLVM and + * the other one sits in compiler-rt/include/profile directory. To make changes + * in this file, first modify the primary copy and copy it over to compiler-rt. + * Testing of any change in this file can start only after the two copies are + * synced up. + * +\*===----------------------------------------------------------------------===*/ + + +#ifdef _MSC_VER +#define PACKED(__decl__) __pragma(pack(push,1)) __decl__ __pragma(pack(pop)) +#else +#define PACKED(__decl__) __decl__ __attribute__((__packed__)) +#endif + +// A 64-bit magic number to uniquely identify the raw binary memprof profile file. +#define MEMPROF_RAW_MAGIC_64 \ + ((uint64_t)255 << 56 | (uint64_t)'m' << 48 | (uint64_t)'p' << 40 | (uint64_t)'r' << 32 | \ + (uint64_t)'o' << 24 | (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129) + +// The version number of the raw binary format. +#define MEMPROF_RAW_VERSION 1ULL + +namespace llvm { +namespace memprof { +// A struct describing the header used for the raw binary memprof profile format. +PACKED(struct Header { + uint64_t Magic; + uint64_t Version; + uint64_t TotalSize; + uint64_t SegmentOffset; + uint64_t MIBOffset; + uint64_t StackOffset; +}); + +// A struct describing the information necessary to describe a /proc/maps +// segment entry for a particular binary/library identified by its build id. +PACKED(struct SegmentEntry { + uint64_t Start; + uint64_t End; + uint64_t Offset; + uint8_t BuildId[32]; +}); +} // namespace memprof +} // namespace llvm + +#endif diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp index b28909152e20..2ff314a5a9cb 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp @@ -130,23 +130,24 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name) // Strict init-order checking is dlopen-hostile: // https://github.com/google/sanitizers/issues/178 -#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \ - do { \ - if (flags()->strict_init_order) \ - StopInitOrderChecking(); \ - CheckNoDeepBind(filename, flag); \ - } while (false) -#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit() -#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) -#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() -#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!asan_inited) -#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) \ - if (AsanThread *t = GetCurrentThread()) { \ - *begin = t->tls_begin(); \ - *end = t->tls_end(); \ - } else { \ - *begin = *end = 0; \ - } +# define COMMON_INTERCEPTOR_DLOPEN(filename, flag) \ + ({ \ + if (flags()->strict_init_order) \ + StopInitOrderChecking(); \ + CheckNoDeepBind(filename, flag); \ + REAL(dlopen)(filename, flag); \ + }) +# define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit() +# define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) +# define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() +# define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!asan_inited) +# define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) \ + if (AsanThread *t = GetCurrentThread()) { \ + *begin = t->tls_begin(); \ + *end = t->tls_end(); \ + } else { \ + *begin = *end = 0; \ + } #define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \ do { \ diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_report.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_report.cpp index 1f266334b311..2a38fabaf220 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_report.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_report.cpp @@ -460,6 +460,10 @@ static bool SuppressErrorReport(uptr pc) { void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write, uptr access_size, u32 exp, bool fatal) { + if (__asan_test_only_reported_buggy_pointer) { + *__asan_test_only_reported_buggy_pointer = addr; + return; + } if (!fatal && SuppressErrorReport(pc)) return; ENABLE_FRAME_POINTER; diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl.cpp index 1b150b393cfe..5be8ef0f6d1c 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl.cpp @@ -85,12 +85,8 @@ void ShowStatsAndAbort() { NOINLINE static void ReportGenericErrorWrapper(uptr addr, bool is_write, int size, int exp_arg, bool fatal) { - if (__asan_test_only_reported_buggy_pointer) { - *__asan_test_only_reported_buggy_pointer = addr; - } else { - GET_CALLER_PC_BP_SP; - ReportGenericError(pc, bp, sp, addr, is_write, size, exp_arg, fatal); - } + GET_CALLER_PC_BP_SP; + ReportGenericError(pc, bp, sp, addr, is_write, size, exp_arg, fatal); } // --------------- LowLevelAllocateCallbac ---------- {{{1 diff --git a/contrib/llvm-project/compiler-rt/lib/cfi/cfi.cpp b/contrib/llvm-project/compiler-rt/lib/cfi/cfi.cpp index 95853208f951..65a10c999cc6 100644 --- a/contrib/llvm-project/compiler-rt/lib/cfi/cfi.cpp +++ b/contrib/llvm-project/compiler-rt/lib/cfi/cfi.cpp @@ -230,7 +230,7 @@ uptr find_cfi_check_in_dso(dl_phdr_info *info) { } if (symtab > strtab) { - VReport(1, "Can not handle: symtab > strtab (%p > %zx)\n", symtab, strtab); + VReport(1, "Can not handle: symtab > strtab (%zx > %zx)\n", symtab, strtab); return 0; } @@ -250,7 +250,7 @@ uptr find_cfi_check_in_dso(dl_phdr_info *info) { if (phdr_idx == info->dlpi_phnum) { // Nope, either different segments or just bogus pointers. // Can not handle this. - VReport(1, "Can not handle: symtab %p, strtab %zx\n", symtab, strtab); + VReport(1, "Can not handle: symtab %zx, strtab %zx\n", symtab, strtab); return 0; } diff --git a/contrib/llvm-project/compiler-rt/lib/memprof/memprof_allocator.cpp b/contrib/llvm-project/compiler-rt/lib/memprof/memprof_allocator.cpp index 696f64d8c324..059ce283b8c9 100644 --- a/contrib/llvm-project/compiler-rt/lib/memprof/memprof_allocator.cpp +++ b/contrib/llvm-project/compiler-rt/lib/memprof/memprof_allocator.cpp @@ -252,6 +252,8 @@ struct Allocator { InsertLiveBlocks(); if (print_text) { + if (!flags()->print_terse) + Printf("Recorded MIBs (incl. live on exit):\n"); MIBMap.ForEach(PrintCallback, reinterpret_cast(flags()->print_terse)); StackDepotPrintAll(); @@ -271,9 +273,6 @@ struct Allocator { // Inserts any blocks which have been allocated but not yet deallocated. void InsertLiveBlocks() { - if (print_text && !flags()->print_terse) - Printf("Live on exit:\n"); - allocator.ForEachChunk( [](uptr chunk, void *alloc) { u64 user_requested_size; diff --git a/contrib/llvm-project/compiler-rt/lib/memprof/memprof_interceptors.cpp b/contrib/llvm-project/compiler-rt/lib/memprof/memprof_interceptors.cpp index 5575ae2fe444..459ad03e8dfe 100644 --- a/contrib/llvm-project/compiler-rt/lib/memprof/memprof_interceptors.cpp +++ b/contrib/llvm-project/compiler-rt/lib/memprof/memprof_interceptors.cpp @@ -93,10 +93,6 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) do { \ } while (false) #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name) -#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \ - do { \ - CheckNoDeepBind(filename, flag); \ - } while (false) #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit() #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() diff --git a/contrib/llvm-project/compiler-rt/lib/memprof/memprof_rawprofile.cpp b/contrib/llvm-project/compiler-rt/lib/memprof/memprof_rawprofile.cpp index 96f315f95b24..c4800a6df34c 100644 --- a/contrib/llvm-project/compiler-rt/lib/memprof/memprof_rawprofile.cpp +++ b/contrib/llvm-project/compiler-rt/lib/memprof/memprof_rawprofile.cpp @@ -1,6 +1,12 @@ -#include "memprof_rawprofile.h" +#include +#include +#include + #include "memprof_meminfoblock.h" +#include "memprof_rawprofile.h" +#include "profile/MemProfData.inc" #include "sanitizer_common/sanitizer_allocator_internal.h" +#include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_linux.h" #include "sanitizer_common/sanitizer_procmaps.h" #include "sanitizer_common/sanitizer_stackdepot.h" @@ -8,29 +14,12 @@ #include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_vector.h" -#include -#include - namespace __memprof { using ::__sanitizer::Vector; +using SegmentEntry = ::llvm::memprof::SegmentEntry; +using Header = ::llvm::memprof::Header; namespace { -typedef struct __attribute__((__packed__)) { - u64 start; - u64 end; - u64 offset; - u8 buildId[32]; -} SegmentEntry; - -typedef struct __attribute__((__packed__)) { - u64 magic; - u64 version; - u64 total_size; - u64 segment_offset; - u64 mib_offset; - u64 stack_offset; -} Header; - template char *WriteBytes(T Pod, char *&Buffer) { *(T *)Buffer = Pod; return Buffer + sizeof(T); @@ -76,12 +65,12 @@ void SerializeSegmentsToBuffer(MemoryMappingLayoutBase &Layout, for (Layout.Reset(); Layout.Next(&segment);) { if (segment.IsReadable() && segment.IsExecutable()) { - SegmentEntry entry{}; - entry.start = segment.start; - entry.end = segment.end; - entry.offset = segment.offset; - memcpy(entry.buildId, segment.uuid, sizeof(segment.uuid)); - memcpy(Ptr, &entry, sizeof(SegmentEntry)); + SegmentEntry Entry{}; + Entry.Start = segment.start; + Entry.End = segment.end; + Entry.Offset = segment.offset; + memcpy(Entry.BuildId, segment.uuid, sizeof(segment.uuid)); + memcpy(Ptr, &Entry, sizeof(SegmentEntry)); Ptr += sizeof(SegmentEntry); NumSegmentsRecorded++; } @@ -89,7 +78,7 @@ void SerializeSegmentsToBuffer(MemoryMappingLayoutBase &Layout, // Store the number of segments we recorded in the space we reserved. *((u64 *)Buffer) = NumSegmentsRecorded; - CHECK(ExpectedNumBytes == static_cast(Ptr - Buffer) && + CHECK(ExpectedNumBytes >= static_cast(Ptr - Buffer) && "Expected num bytes != actual bytes written"); } @@ -144,7 +133,7 @@ void SerializeStackToBuffer(const Vector &StackIds, *(u64 *)(Ptr - (Count + 1) * sizeof(u64)) = Count; } - CHECK(ExpectedNumBytes == static_cast(Ptr - Buffer) && + CHECK(ExpectedNumBytes >= static_cast(Ptr - Buffer) && "Expected num bytes != actual bytes written"); } @@ -172,7 +161,7 @@ void SerializeMIBInfoToBuffer(MIBMapTy &MIBMap, const Vector &StackIds, Ptr = WriteBytes((*h)->mib, Ptr); } - CHECK(ExpectedNumBytes == static_cast(Ptr - Buffer) && + CHECK(ExpectedNumBytes >= static_cast(Ptr - Buffer) && "Expected num bytes != actual bytes written"); } @@ -193,11 +182,15 @@ void SerializeMIBInfoToBuffer(MIBMapTy &MIBMap, const Vector &StackIds, // BuildID 32B // ---------- // ... +// ---------- +// Optional Padding Bytes // ---------- MIB Info // Num Entries // ---------- MIB Entry // Alloc Count // ... +// ---------- +// Optional Padding Bytes // ---------- Stack Info // Num Entries // ---------- Stack Entry @@ -206,23 +199,29 @@ void SerializeMIBInfoToBuffer(MIBMapTy &MIBMap, const Vector &StackIds, // PC2 // ... // ---------- +// Optional Padding Bytes // ... u64 SerializeToRawProfile(MIBMapTy &MIBMap, MemoryMappingLayoutBase &Layout, char *&Buffer) { - const u64 NumSegmentBytes = SegmentSizeBytes(Layout); + // Each section size is rounded up to 8b since the first entry in each section + // is a u64 which holds the number of entries in the section by convention. + const u64 NumSegmentBytes = RoundUpTo(SegmentSizeBytes(Layout), 8); Vector StackIds; MIBMap.ForEach(RecordStackId, reinterpret_cast(&StackIds)); // The first 8b are for the total number of MIB records. Each MIB record is // preceded by a 8b stack id which is associated with stack frames in the next // section. - const u64 NumMIBInfoBytes = - sizeof(u64) + StackIds.Size() * (sizeof(u64) + sizeof(MemInfoBlock)); + const u64 NumMIBInfoBytes = RoundUpTo( + sizeof(u64) + StackIds.Size() * (sizeof(u64) + sizeof(MemInfoBlock)), 8); - const u64 NumStackBytes = StackSizeBytes(StackIds); + const u64 NumStackBytes = RoundUpTo(StackSizeBytes(StackIds), 8); - const u64 TotalSizeBytes = - sizeof(Header) + NumSegmentBytes + NumStackBytes + NumMIBInfoBytes; + // Ensure that the profile is 8b aligned. We allow for some optional padding + // at the end so that any subsequent profile serialized to the same file does + // not incur unaligned accesses. + const u64 TotalSizeBytes = RoundUpTo( + sizeof(Header) + NumSegmentBytes + NumStackBytes + NumMIBInfoBytes, 8); // Allocate the memory for the entire buffer incl. info blocks. Buffer = (char *)InternalAlloc(TotalSizeBytes); diff --git a/contrib/llvm-project/compiler-rt/lib/memprof/memprof_rawprofile.h b/contrib/llvm-project/compiler-rt/lib/memprof/memprof_rawprofile.h index 052bac3267f1..575104e7e34e 100644 --- a/contrib/llvm-project/compiler-rt/lib/memprof/memprof_rawprofile.h +++ b/contrib/llvm-project/compiler-rt/lib/memprof/memprof_rawprofile.h @@ -5,17 +5,10 @@ #include "sanitizer_common/sanitizer_procmaps.h" namespace __memprof { - -// TODO: pull these in from MemProfData.inc -#define MEMPROF_RAW_MAGIC_64 \ - (u64)255 << 56 | (u64)'m' << 48 | (u64)'p' << 40 | (u64)'r' << 32 | \ - (u64)'o' << 24 | (u64)'f' << 16 | (u64)'r' << 8 | (u64)129 - -#define MEMPROF_RAW_VERSION 1ULL - +// Serialize the in-memory representation of the memprof profile to the raw +// binary format. The format itself is documented memprof_rawprofile.cpp. u64 SerializeToRawProfile(MIBMapTy &BlockCache, MemoryMappingLayoutBase &Layout, char *&Buffer); - } // namespace __memprof #endif // MEMPROF_RAWPROFILE_H_ diff --git a/contrib/llvm-project/compiler-rt/lib/memprof/tests/rawprofile.cpp b/contrib/llvm-project/compiler-rt/lib/memprof/tests/rawprofile.cpp index 4404ab86092e..829e18370737 100644 --- a/contrib/llvm-project/compiler-rt/lib/memprof/tests/rawprofile.cpp +++ b/contrib/llvm-project/compiler-rt/lib/memprof/tests/rawprofile.cpp @@ -1,6 +1,10 @@ #include "memprof/memprof_rawprofile.h" +#include +#include + #include "memprof/memprof_meminfoblock.h" +#include "profile/MemProfData.inc" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_procmaps.h" #include "sanitizer_common/sanitizer_stackdepot.h" @@ -8,8 +12,6 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include - namespace { using ::__memprof::MemInfoBlock; @@ -47,6 +49,8 @@ u64 PopulateFakeMap(const MemInfoBlock &FakeMIB, uptr StackPCBegin, template T Read(char *&Buffer) { static_assert(std::is_pod::value, "Must be a POD type."); + assert(reinterpret_cast(Buffer) % sizeof(T) == 0 && + "Unaligned read!"); T t = *reinterpret_cast(Buffer); Buffer += sizeof(T); return t; @@ -101,8 +105,9 @@ TEST(MemProf, Basic) { const u64 MIBOffset = Read(Ptr); const u64 StackOffset = Read(Ptr); - // ============= Check sizes. + // ============= Check sizes and padding. EXPECT_EQ(TotalSize, NumBytes); + EXPECT_EQ(TotalSize % 8, 0ULL); // Should be equal to the size of the raw profile header. EXPECT_EQ(SegmentOffset, 48ULL); @@ -118,8 +123,10 @@ TEST(MemProf, Basic) { EXPECT_EQ(StackOffset, 336ULL); // We expect 2 stack entries, with 5 frames - 8b for total count, - // 2 * (8b for id, 8b for frame count and 5*8b for fake frames) - EXPECT_EQ(TotalSize - StackOffset, 8ULL + 2 * (8 + 8 + 5 * 8)); + // 2 * (8b for id, 8b for frame count and 5*8b for fake frames). + // Since this is the last section, there may be additional padding at the end + // to make the total profile size 8b aligned. + EXPECT_GE(TotalSize - StackOffset, 8ULL + 2 * (8 + 8 + 5 * 8)); // ============= Check contents. unsigned char ExpectedSegmentBytes[64] = { diff --git a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingMerge.c b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingMerge.c index 674b1898b046..80db2527461e 100644 --- a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingMerge.c +++ b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingMerge.c @@ -34,7 +34,8 @@ uint64_t lprofGetLoadModuleSignature() { const __llvm_profile_data *FirstD = __llvm_profile_begin_data(); return (NamesSize << 40) + (CounterSize << 30) + (DataSize << 20) + - (NumVnodes << 10) + (DataSize > 0 ? FirstD->NameRef : 0) + Version; + (NumVnodes << 10) + (DataSize > 0 ? FirstD->NameRef : 0) + Version + + __llvm_profile_get_magic(); } /* Returns 1 if profile is not structurally compatible. */ diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp index bcb7370a7906..af0b0949a88e 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp @@ -24,66 +24,6 @@ namespace __sanitizer { const char *PrimaryAllocatorName = "SizeClassAllocator"; const char *SecondaryAllocatorName = "LargeMmapAllocator"; -// ThreadSanitizer for Go uses libc malloc/free. -#if defined(SANITIZER_USE_MALLOC) -# if SANITIZER_LINUX && !SANITIZER_ANDROID -extern "C" void *__libc_malloc(uptr size); -# if !SANITIZER_GO -extern "C" void *__libc_memalign(uptr alignment, uptr size); -# endif -extern "C" void *__libc_realloc(void *ptr, uptr size); -extern "C" void __libc_free(void *ptr); -# else -# include -# define __libc_malloc malloc -# if !SANITIZER_GO -static void *__libc_memalign(uptr alignment, uptr size) { - void *p; - uptr error = posix_memalign(&p, alignment, size); - if (error) return nullptr; - return p; -} -# endif -# define __libc_realloc realloc -# define __libc_free free -# endif - -static void *RawInternalAlloc(uptr size, InternalAllocatorCache *cache, - uptr alignment) { - (void)cache; -#if !SANITIZER_GO - if (alignment == 0) - return __libc_malloc(size); - else - return __libc_memalign(alignment, size); -#else - // Windows does not provide __libc_memalign/posix_memalign. It provides - // __aligned_malloc, but the allocated blocks can't be passed to free, - // they need to be passed to __aligned_free. InternalAlloc interface does - // not account for such requirement. Alignemnt does not seem to be used - // anywhere in runtime, so just call __libc_malloc for now. - DCHECK_EQ(alignment, 0); - return __libc_malloc(size); -#endif -} - -static void *RawInternalRealloc(void *ptr, uptr size, - InternalAllocatorCache *cache) { - (void)cache; - return __libc_realloc(ptr, size); -} - -static void RawInternalFree(void *ptr, InternalAllocatorCache *cache) { - (void)cache; - __libc_free(ptr); -} - -InternalAllocator *internal_allocator() { - return 0; -} - -#else // SANITIZER_GO || defined(SANITIZER_USE_MALLOC) - static ALIGNED(64) char internal_alloc_placeholder[sizeof(InternalAllocator)]; static atomic_uint8_t internal_allocator_initialized; static StaticSpinMutex internal_alloc_init_mu; @@ -135,8 +75,6 @@ static void RawInternalFree(void *ptr, InternalAllocatorCache *cache) { internal_allocator()->Deallocate(cache, ptr); } -#endif // SANITIZER_GO || defined(SANITIZER_USE_MALLOC) - static void NORETURN ReportInternalAllocatorOutOfMemory(uptr requested_size) { SetAllocatorOutOfMemory(); Report("FATAL: %s: internal allocator is out of memory trying to allocate " @@ -187,6 +125,16 @@ void InternalFree(void *addr, InternalAllocatorCache *cache) { RawInternalFree(addr, cache); } +void InternalAllocatorLock() NO_THREAD_SAFETY_ANALYSIS { + internal_allocator_cache_mu.Lock(); + internal_allocator()->ForceLock(); +} + +void InternalAllocatorUnlock() NO_THREAD_SAFETY_ANALYSIS { + internal_allocator()->ForceUnlock(); + internal_allocator_cache_mu.Unlock(); +} + // LowLevelAllocator constexpr uptr kLowLevelAllocatorDefaultAlignment = 8; static uptr low_level_alloc_min_alignment = kLowLevelAllocatorDefaultAlignment; diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h index 32849036fd04..38994736877a 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h @@ -48,6 +48,8 @@ void *InternalReallocArray(void *p, uptr count, uptr size, void *InternalCalloc(uptr count, uptr size, InternalAllocatorCache *cache = nullptr); void InternalFree(void *p, InternalAllocatorCache *cache = nullptr); +void InternalAllocatorLock(); +void InternalAllocatorUnlock(); InternalAllocator *internal_allocator(); } // namespace __sanitizer diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 065154496eb5..6ec6bb4bd856 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -460,6 +460,10 @@ template constexpr T Max(T a, T b) { return a > b ? a : b; } +template +constexpr T Abs(T a) { + return a < 0 ? -a : a; +} template void Swap(T& a, T& b) { T tmp = a; a = b; diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index abb38ccfa15d..d219734fa0a3 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -21,7 +21,7 @@ // COMMON_INTERCEPTOR_FD_RELEASE // COMMON_INTERCEPTOR_FD_ACCESS // COMMON_INTERCEPTOR_SET_THREAD_NAME -// COMMON_INTERCEPTOR_ON_DLOPEN +// COMMON_INTERCEPTOR_DLOPEN // COMMON_INTERCEPTOR_ON_EXIT // COMMON_INTERCEPTOR_MUTEX_PRE_LOCK // COMMON_INTERCEPTOR_MUTEX_POST_LOCK @@ -206,9 +206,9 @@ extern const short *_tolower_tab_; COMMON_INTERCEPTOR_READ_RANGE((ctx), (s), \ common_flags()->strict_string_checks ? (internal_strlen(s)) + 1 : (n) ) -#ifndef COMMON_INTERCEPTOR_ON_DLOPEN -#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \ - CheckNoDeepBind(filename, flag); +#ifndef COMMON_INTERCEPTOR_DLOPEN +#define COMMON_INTERCEPTOR_DLOPEN(filename, flag) \ + ({ CheckNoDeepBind(filename, flag); REAL(dlopen)(filename, flag); }) #endif #ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE @@ -6380,8 +6380,7 @@ INTERCEPTOR(void*, dlopen, const char *filename, int flag) { void *ctx; COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag); if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0); - COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag); - void *res = REAL(dlopen)(filename, flag); + void *res = COMMON_INTERCEPTOR_DLOPEN(filename, flag); Symbolizer::GetOrInit()->InvalidateModuleList(); COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res); return res; diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_dense_map.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_dense_map.h index 3fa6af76ce29..046d77dddc9c 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_dense_map.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_dense_map.h @@ -226,28 +226,26 @@ class DenseMapBase { return FindAndConstruct(__sanitizer::move(Key)).second; } - /// Equality comparison for DenseMap. + /// Iterate over active entries of the container. /// - /// Iterates over elements of LHS confirming that each (key, value) pair in - /// LHS is also in RHS, and that no additional pairs are in RHS. Equivalent to - /// N calls to RHS.find and N value comparisons. Amortized complexity is - /// linear, worst case is O(N^2) (if every hash collides). - bool operator==(const DenseMapBase &RHS) const { - if (size() != RHS.size()) - return false; - + /// Function can return fast to stop the process. + template + void forEach(Fn fn) { const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); for (auto *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) { const KeyT K = P->getFirst(); if (!KeyInfoT::isEqual(K, EmptyKey) && !KeyInfoT::isEqual(K, TombstoneKey)) { - const auto *I = RHS.find(K); - if (!I || P->getSecond() != I->getSecond()) - return false; + if (!fn(*P)) + return; } } + } - return true; + template + void forEach(Fn fn) const { + const_cast(this)->forEach( + [&](const value_type &KV) { return fn(KV); }); } protected: @@ -524,6 +522,35 @@ class DenseMapBase { } }; +/// Equality comparison for DenseMap. +/// +/// Iterates over elements of LHS confirming that each (key, value) pair in LHS +/// is also in RHS, and that no additional pairs are in RHS. +/// Equivalent to N calls to RHS.find and N value comparisons. Amortized +/// complexity is linear, worst case is O(N^2) (if every hash collides). +template +bool operator==( + const DenseMapBase &LHS, + const DenseMapBase &RHS) { + if (LHS.size() != RHS.size()) + return false; + + bool R = true; + LHS.forEach( + [&](const typename DenseMapBase::value_type &KV) -> bool { + const auto *I = RHS.find(KV.first); + if (!I || I->second != KV.second) { + R = false; + return false; + } + return true; + }); + + return R; +} + /// Inequality comparison for DenseMap. /// /// Equivalent to !(LHS == RHS). See operator== for performance notes. diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_dense_map_info.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_dense_map_info.h index 85c6427906c1..f4640369ae58 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_dense_map_info.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_dense_map_info.h @@ -18,7 +18,7 @@ namespace __sanitizer { namespace detail { /// Simplistic combination of 32-bit hash values into 32-bit hash values. -static inline unsigned combineHashValue(unsigned a, unsigned b) { +static constexpr unsigned combineHashValue(unsigned a, unsigned b) { u64 key = (u64)a << 32 | (u64)b; key += ~(key << 32); key ^= (key >> 22); @@ -37,18 +37,19 @@ template struct DenseMapPair { KeyT first = {}; ValueT second = {}; - DenseMapPair() = default; - DenseMapPair(const KeyT &f, const ValueT &s) : first(f), second(s) {} + constexpr DenseMapPair() = default; + constexpr DenseMapPair(const KeyT &f, const ValueT &s) + : first(f), second(s) {} template - DenseMapPair(KeyT2 &&f, ValueT2 &&s) + constexpr DenseMapPair(KeyT2 &&f, ValueT2 &&s) : first(__sanitizer::forward(f)), second(__sanitizer::forward(s)) {} - DenseMapPair(const DenseMapPair &other) = default; - DenseMapPair &operator=(const DenseMapPair &other) = default; - DenseMapPair(DenseMapPair &&other) = default; - DenseMapPair &operator=(DenseMapPair &&other) = default; + constexpr DenseMapPair(const DenseMapPair &other) = default; + constexpr DenseMapPair &operator=(const DenseMapPair &other) = default; + constexpr DenseMapPair(DenseMapPair &&other) = default; + constexpr DenseMapPair &operator=(DenseMapPair &&other) = default; KeyT &getFirst() { return first; } const KeyT &getFirst() const { return first; } @@ -60,8 +61,8 @@ struct DenseMapPair { template struct DenseMapInfo { - // static inline T getEmptyKey(); - // static inline T getTombstoneKey(); + // static T getEmptyKey(); + // static T getTombstoneKey(); // static unsigned getHashValue(const T &Val); // static bool isEqual(const T &LHS, const T &RHS); }; @@ -79,43 +80,50 @@ struct DenseMapInfo { // "Log2MaxAlign bits of alignment"); static constexpr uptr Log2MaxAlign = 12; - static inline T *getEmptyKey() { + static constexpr T *getEmptyKey() { uptr Val = static_cast(-1); Val <<= Log2MaxAlign; return reinterpret_cast(Val); } - static inline T *getTombstoneKey() { + static constexpr T *getTombstoneKey() { uptr Val = static_cast(-2); Val <<= Log2MaxAlign; return reinterpret_cast(Val); } - static unsigned getHashValue(const T *PtrVal) { + static constexpr unsigned getHashValue(const T *PtrVal) { return (unsigned((uptr)PtrVal) >> 4) ^ (unsigned((uptr)PtrVal) >> 9); } - static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; } + static constexpr bool isEqual(const T *LHS, const T *RHS) { + return LHS == RHS; + } }; // Provide DenseMapInfo for chars. template <> struct DenseMapInfo { - static inline char getEmptyKey() { return ~0; } - static inline char getTombstoneKey() { return ~0 - 1; } - static unsigned getHashValue(const char &Val) { return Val * 37U; } + static constexpr char getEmptyKey() { return ~0; } + static constexpr char getTombstoneKey() { return ~0 - 1; } + static constexpr unsigned getHashValue(const char &Val) { return Val * 37U; } - static bool isEqual(const char &LHS, const char &RHS) { return LHS == RHS; } + static constexpr bool isEqual(const char &LHS, const char &RHS) { + return LHS == RHS; + } }; // Provide DenseMapInfo for unsigned chars. template <> struct DenseMapInfo { - static inline unsigned char getEmptyKey() { return ~0; } - static inline unsigned char getTombstoneKey() { return ~0 - 1; } - static unsigned getHashValue(const unsigned char &Val) { return Val * 37U; } + static constexpr unsigned char getEmptyKey() { return ~0; } + static constexpr unsigned char getTombstoneKey() { return ~0 - 1; } + static constexpr unsigned getHashValue(const unsigned char &Val) { + return Val * 37U; + } - static bool isEqual(const unsigned char &LHS, const unsigned char &RHS) { + static constexpr bool isEqual(const unsigned char &LHS, + const unsigned char &RHS) { return LHS == RHS; } }; @@ -123,11 +131,14 @@ struct DenseMapInfo { // Provide DenseMapInfo for unsigned shorts. template <> struct DenseMapInfo { - static inline unsigned short getEmptyKey() { return 0xFFFF; } - static inline unsigned short getTombstoneKey() { return 0xFFFF - 1; } - static unsigned getHashValue(const unsigned short &Val) { return Val * 37U; } + static constexpr unsigned short getEmptyKey() { return 0xFFFF; } + static constexpr unsigned short getTombstoneKey() { return 0xFFFF - 1; } + static constexpr unsigned getHashValue(const unsigned short &Val) { + return Val * 37U; + } - static bool isEqual(const unsigned short &LHS, const unsigned short &RHS) { + static constexpr bool isEqual(const unsigned short &LHS, + const unsigned short &RHS) { return LHS == RHS; } }; @@ -135,11 +146,13 @@ struct DenseMapInfo { // Provide DenseMapInfo for unsigned ints. template <> struct DenseMapInfo { - static inline unsigned getEmptyKey() { return ~0U; } - static inline unsigned getTombstoneKey() { return ~0U - 1; } - static unsigned getHashValue(const unsigned &Val) { return Val * 37U; } + static constexpr unsigned getEmptyKey() { return ~0U; } + static constexpr unsigned getTombstoneKey() { return ~0U - 1; } + static constexpr unsigned getHashValue(const unsigned &Val) { + return Val * 37U; + } - static bool isEqual(const unsigned &LHS, const unsigned &RHS) { + static constexpr bool isEqual(const unsigned &LHS, const unsigned &RHS) { return LHS == RHS; } }; @@ -147,14 +160,15 @@ struct DenseMapInfo { // Provide DenseMapInfo for unsigned longs. template <> struct DenseMapInfo { - static inline unsigned long getEmptyKey() { return ~0UL; } - static inline unsigned long getTombstoneKey() { return ~0UL - 1L; } + static constexpr unsigned long getEmptyKey() { return ~0UL; } + static constexpr unsigned long getTombstoneKey() { return ~0UL - 1L; } - static unsigned getHashValue(const unsigned long &Val) { + static constexpr unsigned getHashValue(const unsigned long &Val) { return (unsigned)(Val * 37UL); } - static bool isEqual(const unsigned long &LHS, const unsigned long &RHS) { + static constexpr bool isEqual(const unsigned long &LHS, + const unsigned long &RHS) { return LHS == RHS; } }; @@ -162,15 +176,15 @@ struct DenseMapInfo { // Provide DenseMapInfo for unsigned long longs. template <> struct DenseMapInfo { - static inline unsigned long long getEmptyKey() { return ~0ULL; } - static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; } + static constexpr unsigned long long getEmptyKey() { return ~0ULL; } + static constexpr unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; } - static unsigned getHashValue(const unsigned long long &Val) { + static constexpr unsigned getHashValue(const unsigned long long &Val) { return (unsigned)(Val * 37ULL); } - static bool isEqual(const unsigned long long &LHS, - const unsigned long long &RHS) { + static constexpr bool isEqual(const unsigned long long &LHS, + const unsigned long long &RHS) { return LHS == RHS; } }; @@ -178,51 +192,59 @@ struct DenseMapInfo { // Provide DenseMapInfo for shorts. template <> struct DenseMapInfo { - static inline short getEmptyKey() { return 0x7FFF; } - static inline short getTombstoneKey() { return -0x7FFF - 1; } - static unsigned getHashValue(const short &Val) { return Val * 37U; } - static bool isEqual(const short &LHS, const short &RHS) { return LHS == RHS; } + static constexpr short getEmptyKey() { return 0x7FFF; } + static constexpr short getTombstoneKey() { return -0x7FFF - 1; } + static constexpr unsigned getHashValue(const short &Val) { return Val * 37U; } + static constexpr bool isEqual(const short &LHS, const short &RHS) { + return LHS == RHS; + } }; // Provide DenseMapInfo for ints. template <> struct DenseMapInfo { - static inline int getEmptyKey() { return 0x7fffffff; } - static inline int getTombstoneKey() { return -0x7fffffff - 1; } - static unsigned getHashValue(const int &Val) { return (unsigned)(Val * 37U); } + static constexpr int getEmptyKey() { return 0x7fffffff; } + static constexpr int getTombstoneKey() { return -0x7fffffff - 1; } + static constexpr unsigned getHashValue(const int &Val) { + return (unsigned)(Val * 37U); + } - static bool isEqual(const int &LHS, const int &RHS) { return LHS == RHS; } + static constexpr bool isEqual(const int &LHS, const int &RHS) { + return LHS == RHS; + } }; // Provide DenseMapInfo for longs. template <> struct DenseMapInfo { - static inline long getEmptyKey() { + static constexpr long getEmptyKey() { return (1UL << (sizeof(long) * 8 - 1)) - 1UL; } - static inline long getTombstoneKey() { return getEmptyKey() - 1L; } + static constexpr long getTombstoneKey() { return getEmptyKey() - 1L; } - static unsigned getHashValue(const long &Val) { + static constexpr unsigned getHashValue(const long &Val) { return (unsigned)(Val * 37UL); } - static bool isEqual(const long &LHS, const long &RHS) { return LHS == RHS; } + static constexpr bool isEqual(const long &LHS, const long &RHS) { + return LHS == RHS; + } }; // Provide DenseMapInfo for long longs. template <> struct DenseMapInfo { - static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; } - static inline long long getTombstoneKey() { + static constexpr long long getEmptyKey() { return 0x7fffffffffffffffLL; } + static constexpr long long getTombstoneKey() { return -0x7fffffffffffffffLL - 1; } - static unsigned getHashValue(const long long &Val) { + static constexpr unsigned getHashValue(const long long &Val) { return (unsigned)(Val * 37ULL); } - static bool isEqual(const long long &LHS, const long long &RHS) { + static constexpr bool isEqual(const long long &LHS, const long long &RHS) { return LHS == RHS; } }; @@ -234,22 +256,22 @@ struct DenseMapInfo> { using FirstInfo = DenseMapInfo; using SecondInfo = DenseMapInfo; - static inline Pair getEmptyKey() { + static constexpr Pair getEmptyKey() { return detail::DenseMapPair(FirstInfo::getEmptyKey(), SecondInfo::getEmptyKey()); } - static inline Pair getTombstoneKey() { + static constexpr Pair getTombstoneKey() { return detail::DenseMapPair(FirstInfo::getTombstoneKey(), SecondInfo::getTombstoneKey()); } - static unsigned getHashValue(const Pair &PairVal) { + static constexpr unsigned getHashValue(const Pair &PairVal) { return detail::combineHashValue(FirstInfo::getHashValue(PairVal.first), SecondInfo::getHashValue(PairVal.second)); } - static bool isEqual(const Pair &LHS, const Pair &RHS) { + static constexpr bool isEqual(const Pair &LHS, const Pair &RHS) { return FirstInfo::isEqual(LHS.first, RHS.first) && SecondInfo::isEqual(LHS.second, RHS.second); } diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp index c7b30d988365..9b5f6f1da1a1 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp @@ -274,6 +274,15 @@ void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name) { UNIMPLEMENTED(); } +bool MprotectNoAccess(uptr addr, uptr size) { + return _zx_vmar_protect(_zx_vmar_root_self(), 0, Addr, Size) == ZX_OK; +} + +bool MprotectReadOnly(uptr addr, uptr size) { + return _zx_vmar_protect(_zx_vmar_root_self(), ZX_VM_PERM_READ, Addr, Size) == + ZX_OK; +} + void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment, const char *mem_type) { CHECK_GE(size, GetPageSize()); diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_leb128.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_leb128.h new file mode 100644 index 000000000000..553550d29552 --- /dev/null +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_leb128.h @@ -0,0 +1,87 @@ +//===-- sanitizer_leb128.h --------------------------------------*- 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 SANITIZER_LEB128_H +#define SANITIZER_LEB128_H + +#include "sanitizer_common.h" +#include "sanitizer_internal_defs.h" + +namespace __sanitizer { + +template +It EncodeSLEB128(T value, It begin, It end) { + bool more; + do { + u8 byte = value & 0x7f; + // NOTE: this assumes that this signed shift is an arithmetic right shift. + value >>= 7; + more = !((((value == 0) && ((byte & 0x40) == 0)) || + ((value == -1) && ((byte & 0x40) != 0)))); + if (more) + byte |= 0x80; + if (UNLIKELY(begin == end)) + break; + *(begin++) = byte; + } while (more); + return begin; +} + +template +It DecodeSLEB128(It begin, It end, T* v) { + T value = 0; + unsigned shift = 0; + u8 byte; + do { + if (UNLIKELY(begin == end)) + return begin; + byte = *(begin++); + T slice = byte & 0x7f; + value |= slice << shift; + shift += 7; + } while (byte >= 128); + if (shift < 64 && (byte & 0x40)) + value |= (-1ULL) << shift; + *v = value; + return begin; +} + +template +It EncodeULEB128(T value, It begin, It end) { + do { + u8 byte = value & 0x7f; + value >>= 7; + if (value) + byte |= 0x80; + if (UNLIKELY(begin == end)) + break; + *(begin++) = byte; + } while (value); + return begin; +} + +template +It DecodeULEB128(It begin, It end, T* v) { + T value = 0; + unsigned shift = 0; + u8 byte; + do { + if (UNLIKELY(begin == end)) + return begin; + byte = *(begin++); + T slice = byte & 0x7f; + value += slice << shift; + shift += 7; + } while (byte >= 128); + *v = value; + return begin; +} + +} // namespace __sanitizer + +#endif // SANITIZER_LEB128_H diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 7f9e1064b05f..37e3658c319d 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -1761,6 +1761,8 @@ HandleSignalMode GetHandleSignalMode(int signum) { #if !SANITIZER_GO void *internal_start_thread(void *(*func)(void *arg), void *arg) { + if (&real_pthread_create == 0) + return nullptr; // Start the thread with signals blocked, otherwise it can steal user signals. ScopedBlockSignals block(nullptr); void *th; @@ -1769,7 +1771,8 @@ void *internal_start_thread(void *(*func)(void *arg), void *arg) { } void internal_join_thread(void *th) { - real_pthread_join(th, nullptr); + if (&real_pthread_join) + real_pthread_join(th, nullptr); } #else void *internal_start_thread(void *(*func)(void *), void *arg) { return 0; } diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp index b67203d4c10e..f9b5c531aeee 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp @@ -265,30 +265,32 @@ int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp, static fd_t internal_spawn_impl(const char *argv[], const char *envp[], pid_t *pid) { - fd_t master_fd = kInvalidFd; - fd_t slave_fd = kInvalidFd; + fd_t primary_fd = kInvalidFd; + fd_t secondary_fd = kInvalidFd; auto fd_closer = at_scope_exit([&] { - internal_close(master_fd); - internal_close(slave_fd); + internal_close(primary_fd); + internal_close(secondary_fd); }); // We need a new pseudoterminal to avoid buffering problems. The 'atos' tool // in particular detects when it's talking to a pipe and forgets to flush the // output stream after sending a response. - master_fd = posix_openpt(O_RDWR); - if (master_fd == kInvalidFd) return kInvalidFd; + primary_fd = posix_openpt(O_RDWR); + if (primary_fd == kInvalidFd) + return kInvalidFd; - int res = grantpt(master_fd) || unlockpt(master_fd); + int res = grantpt(primary_fd) || unlockpt(primary_fd); if (res != 0) return kInvalidFd; // Use TIOCPTYGNAME instead of ptsname() to avoid threading problems. - char slave_pty_name[128]; - res = ioctl(master_fd, TIOCPTYGNAME, slave_pty_name); + char secondary_pty_name[128]; + res = ioctl(primary_fd, TIOCPTYGNAME, secondary_pty_name); if (res == -1) return kInvalidFd; - slave_fd = internal_open(slave_pty_name, O_RDWR); - if (slave_fd == kInvalidFd) return kInvalidFd; + secondary_fd = internal_open(secondary_pty_name, O_RDWR); + if (secondary_fd == kInvalidFd) + return kInvalidFd; // File descriptor actions posix_spawn_file_actions_t acts; @@ -299,9 +301,9 @@ static fd_t internal_spawn_impl(const char *argv[], const char *envp[], posix_spawn_file_actions_destroy(&acts); }); - res = posix_spawn_file_actions_adddup2(&acts, slave_fd, STDIN_FILENO) || - posix_spawn_file_actions_adddup2(&acts, slave_fd, STDOUT_FILENO) || - posix_spawn_file_actions_addclose(&acts, slave_fd); + res = posix_spawn_file_actions_adddup2(&acts, secondary_fd, STDIN_FILENO) || + posix_spawn_file_actions_adddup2(&acts, secondary_fd, STDOUT_FILENO) || + posix_spawn_file_actions_addclose(&acts, secondary_fd); if (res != 0) return kInvalidFd; // Spawn attributes @@ -326,14 +328,14 @@ static fd_t internal_spawn_impl(const char *argv[], const char *envp[], // Disable echo in the new terminal, disable CR. struct termios termflags; - tcgetattr(master_fd, &termflags); + tcgetattr(primary_fd, &termflags); termflags.c_oflag &= ~ONLCR; termflags.c_lflag &= ~ECHO; - tcsetattr(master_fd, TCSANOW, &termflags); + tcsetattr(primary_fd, TCSANOW, &termflags); - // On success, do not close master_fd on scope exit. - fd_t fd = master_fd; - master_fd = kInvalidFd; + // On success, do not close primary_fd on scope exit. + fd_t fd = primary_fd; + primary_fd = kInvalidFd; return fd; } diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.cpp index ad88e2bbbefc..b1c15d8c2834 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.cpp @@ -14,78 +14,187 @@ namespace __sanitizer { -static constexpr u32 kStackSizeBits = 16; +namespace { +struct StackTraceHeader { + static constexpr u32 kStackSizeBits = 8; -StackStore::Id StackStore::Store(const StackTrace &trace) { - uptr *stack_trace = Alloc(trace.size + 1); - CHECK_LT(trace.size, 1 << kStackSizeBits); - *stack_trace = trace.size + (trace.tag << kStackSizeBits); - internal_memcpy(stack_trace + 1, trace.trace, trace.size * sizeof(uptr)); - return reinterpret_cast(stack_trace); + u8 size; + u8 tag; + explicit StackTraceHeader(const StackTrace &trace) + : size(Min(trace.size, (1u << 8) - 1)), tag(trace.tag) { + CHECK_EQ(trace.tag, static_cast(tag)); + } + explicit StackTraceHeader(uptr h) + : size(h & ((1 << kStackSizeBits) - 1)), tag(h >> kStackSizeBits) {} + + uptr ToUptr() const { + return static_cast(size) | (static_cast(tag) << kStackSizeBits); + } +}; +} // namespace + +StackStore::Id StackStore::Store(const StackTrace &trace, uptr *pack) { + if (!trace.size && !trace.tag) + return 0; + StackTraceHeader h(trace); + uptr idx = 0; + *pack = 0; + uptr *stack_trace = Alloc(h.size + 1, &idx, pack); + *stack_trace = h.ToUptr(); + internal_memcpy(stack_trace + 1, trace.trace, h.size * sizeof(uptr)); + *pack += blocks_[GetBlockIdx(idx)].Stored(h.size + 1); + return OffsetToId(idx); } StackTrace StackStore::Load(Id id) { - const uptr *stack_trace = reinterpret_cast(id); - uptr size = *stack_trace & ((1 << kStackSizeBits) - 1); - uptr tag = *stack_trace >> kStackSizeBits; - return StackTrace(stack_trace + 1, size, tag); + if (!id) + return {}; + uptr idx = IdToOffset(id); + uptr block_idx = GetBlockIdx(idx); + CHECK_LT(block_idx, ARRAY_SIZE(blocks_)); + const uptr *stack_trace = blocks_[block_idx].GetOrUnpack(); + if (!stack_trace) + return {}; + stack_trace += GetInBlockIdx(idx); + StackTraceHeader h(*stack_trace); + return StackTrace(stack_trace + 1, h.size, h.tag); } -uptr *StackStore::TryAlloc(uptr count) { - // Optimisic lock-free allocation, essentially try to bump the region ptr. +uptr StackStore::Allocated() const { + uptr next_block = GetBlockIdx( + RoundUpTo(atomic_load_relaxed(&total_frames_), kBlockSizeFrames)); + uptr res = 0; + for (uptr i = 0; i < next_block; ++i) res += blocks_[i].Allocated(); + return res + sizeof(*this); +} + +uptr *StackStore::Alloc(uptr count, uptr *idx, uptr *pack) { for (;;) { - uptr cmp = atomic_load(®ion_pos_, memory_order_acquire); - uptr end = atomic_load(®ion_end_, memory_order_acquire); - uptr size = count * sizeof(uptr); - if (cmp == 0 || cmp + size > end) - return nullptr; - if (atomic_compare_exchange_weak(®ion_pos_, &cmp, cmp + size, - memory_order_acquire)) - return reinterpret_cast(cmp); + // Optimisic lock-free allocation, essentially try to bump the + // total_frames_. + uptr start = atomic_fetch_add(&total_frames_, count, memory_order_relaxed); + uptr block_idx = GetBlockIdx(start); + uptr last_idx = GetBlockIdx(start + count - 1); + if (LIKELY(block_idx == last_idx)) { + // Fits into the a single block. + CHECK_LT(block_idx, ARRAY_SIZE(blocks_)); + *idx = start; + return blocks_[block_idx].GetOrCreate() + GetInBlockIdx(start); + } + + // Retry. We can't use range allocated in two different blocks. + CHECK_LE(count, kBlockSizeFrames); + uptr in_first = kBlockSizeFrames - GetInBlockIdx(start); + // Mark tail/head of these blocks as "stored".to avoid waiting before we can + // Pack(). + *pack += blocks_[block_idx].Stored(in_first); + *pack += blocks_[last_idx].Stored(count - in_first); } } -uptr *StackStore::Alloc(uptr count) { - // First, try to allocate optimisitically. - uptr *s = TryAlloc(count); - if (LIKELY(s)) - return s; - return RefillAndAlloc(count); -} - -uptr *StackStore::RefillAndAlloc(uptr count) { - // If failed, lock, retry and alloc new superblock. - SpinMutexLock l(&mtx_); - for (;;) { - uptr *s = TryAlloc(count); - if (s) - return s; - atomic_store(®ion_pos_, 0, memory_order_relaxed); - uptr size = count * sizeof(uptr) + sizeof(BlockInfo); - uptr allocsz = RoundUpTo(Max(size, 64u * 1024u), GetPageSizeCached()); - uptr mem = (uptr)MmapOrDie(allocsz, "stack depot"); - BlockInfo *new_block = (BlockInfo *)(mem + allocsz) - 1; - new_block->next = curr_; - new_block->ptr = mem; - new_block->size = allocsz; - curr_ = new_block; - - atomic_fetch_add(&mapped_size_, allocsz, memory_order_relaxed); - - allocsz -= sizeof(BlockInfo); - atomic_store(®ion_end_, mem + allocsz, memory_order_release); - atomic_store(®ion_pos_, mem, memory_order_release); - } +uptr StackStore::Pack(Compression type) { + uptr res = 0; + for (BlockInfo &b : blocks_) res += b.Pack(type); + return res; } void StackStore::TestOnlyUnmap() { - while (curr_) { - uptr mem = curr_->ptr; - uptr allocsz = curr_->size; - curr_ = curr_->next; - UnmapOrDie((void *)mem, allocsz); - } + for (BlockInfo &b : blocks_) b.TestOnlyUnmap(); internal_memset(this, 0, sizeof(*this)); } +uptr *StackStore::BlockInfo::Get() const { + // Idiomatic double-checked locking uses memory_order_acquire here. But + // relaxed is find for us, justification is similar to + // TwoLevelMap::GetOrCreate. + return reinterpret_cast(atomic_load_relaxed(&data_)); +} + +uptr *StackStore::BlockInfo::Create() { + SpinMutexLock l(&mtx_); + uptr *ptr = Get(); + if (!ptr) { + ptr = reinterpret_cast( + MmapNoReserveOrDie(kBlockSizeBytes, "StackStore")); + atomic_store(&data_, reinterpret_cast(ptr), memory_order_release); + } + return ptr; +} + +uptr *StackStore::BlockInfo::GetOrCreate() { + uptr *ptr = Get(); + if (LIKELY(ptr)) + return ptr; + return Create(); +} + +uptr *StackStore::BlockInfo::GetOrUnpack() { + SpinMutexLock l(&mtx_); + switch (state) { + case State::Storing: + state = State::Unpacked; + FALLTHROUGH; + case State::Unpacked: + return Get(); + case State::Packed: + break; + } + + uptr *ptr = Get(); + CHECK_NE(nullptr, ptr); + // Fake unpacking. + for (uptr i = 0; i < kBlockSizeFrames; ++i) ptr[i] = ~ptr[i]; + state = State::Unpacked; + return Get(); +} + +uptr StackStore::BlockInfo::Pack(Compression type) { + if (type == Compression::None) + return 0; + + SpinMutexLock l(&mtx_); + switch (state) { + case State::Unpacked: + case State::Packed: + return 0; + case State::Storing: + break; + } + + uptr *ptr = Get(); + if (!ptr || !Stored(0)) + return 0; + + // Fake packing. + for (uptr i = 0; i < kBlockSizeFrames; ++i) ptr[i] = ~ptr[i]; + state = State::Packed; + return kBlockSizeBytes - kBlockSizeBytes / 10; +} + +uptr StackStore::BlockInfo::Allocated() const { + SpinMutexLock l(&mtx_); + switch (state) { + case State::Packed: + return kBlockSizeBytes / 10; + case State::Unpacked: + case State::Storing: + return kBlockSizeBytes; + } +} + +void StackStore::BlockInfo::TestOnlyUnmap() { + if (uptr *ptr = Get()) + UnmapOrDie(ptr, StackStore::kBlockSizeBytes); +} + +bool StackStore::BlockInfo::Stored(uptr n) { + return n + atomic_fetch_add(&stored_, n, memory_order_release) == + kBlockSizeFrames; +} + +bool StackStore::BlockInfo::IsPacked() const { + SpinMutexLock l(&mtx_); + return state == State::Packed; +} + } // namespace __sanitizer diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.h index b5bbdccc20b1..e0bc4e9c4a45 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.h @@ -10,6 +10,7 @@ #define SANITIZER_STACK_STORE_H #include "sanitizer_atomic.h" +#include "sanitizer_common.h" #include "sanitizer_internal_defs.h" #include "sanitizer_mutex.h" #include "sanitizer_stacktrace.h" @@ -17,32 +18,91 @@ namespace __sanitizer { class StackStore { + static constexpr uptr kBlockSizeFrames = 0x100000; + static constexpr uptr kBlockCount = 0x1000; + static constexpr uptr kBlockSizeBytes = kBlockSizeFrames * sizeof(uptr); + public: + enum class Compression : u8 { + None = 0, + Test, + }; + constexpr StackStore() = default; - using Id = uptr; + using Id = u32; // Enough for 2^32 * sizeof(uptr) bytes of traces. + static_assert(u64(kBlockCount) * kBlockSizeFrames == 1ull << (sizeof(Id) * 8), + ""); - Id Store(const StackTrace &trace); + Id Store(const StackTrace &trace, + uptr *pack /* number of blocks completed by this call */); StackTrace Load(Id id); - uptr Allocated() const { return atomic_load_relaxed(&mapped_size_); } + uptr Allocated() const; + + // Packs all blocks which don't expect any more writes. A block is going to be + // packed once. As soon trace from that block was requested, it will unpack + // and stay unpacked after that. + // Returns the number of released bytes. + uptr Pack(Compression type); void TestOnlyUnmap(); private: - uptr *Alloc(uptr count = 1); - uptr *TryAlloc(uptr count); - uptr *RefillAndAlloc(uptr count); - mutable StaticSpinMutex mtx_ = {}; // Protects alloc of new blocks. - atomic_uintptr_t region_pos_ = {}; // Region allocator for Node's. - atomic_uintptr_t region_end_ = {}; - atomic_uintptr_t mapped_size_ = {}; + friend class StackStoreTest; + static constexpr uptr GetBlockIdx(uptr frame_idx) { + return frame_idx / kBlockSizeFrames; + } - struct BlockInfo { - const BlockInfo *next; - uptr ptr; - uptr size; + static constexpr uptr GetInBlockIdx(uptr frame_idx) { + return frame_idx % kBlockSizeFrames; + } + + static constexpr uptr IdToOffset(Id id) { + CHECK_NE(id, 0); + return id - 1; // Avoid zero as id. + } + + static constexpr uptr OffsetToId(Id id) { + // This makes UINT32_MAX to 0 and it will be retrived as and empty stack. + // But this is not a problem as we will not be able to store anything after + // that anyway. + return id + 1; // Avoid zero as id. + } + + uptr *Alloc(uptr count, uptr *idx, uptr *pack); + + // Total number of allocated frames. + atomic_uintptr_t total_frames_ = {}; + + // Each block will hold pointer to exactly kBlockSizeFrames. + class BlockInfo { + atomic_uintptr_t data_; + // Counter to track store progress to know when we can Pack() the block. + atomic_uint32_t stored_; + // Protects alloc of new blocks. + mutable StaticSpinMutex mtx_; + + enum class State : u8 { + Storing = 0, + Packed, + Unpacked, + }; + State state GUARDED_BY(mtx_); + + uptr *Create(); + + public: + uptr *Get() const; + uptr *GetOrCreate(); + uptr *GetOrUnpack(); + uptr Pack(Compression type); + uptr Allocated() const; + void TestOnlyUnmap(); + bool Stored(uptr n); + bool IsPacked() const; }; - const BlockInfo *curr_ = nullptr; + + BlockInfo blocks_[kBlockCount] = {}; }; } // namespace __sanitizer diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp index e203b2cc4c89..527221b0c85c 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp @@ -23,6 +23,7 @@ struct StackDepotNode { using hash_type = u64; hash_type stack_hash; u32 link; + StackStore::Id store_id; static const u32 kTabSizeLog = SANITIZER_ANDROID ? 16 : 20; @@ -53,11 +54,6 @@ static StackStore stackStore; typedef StackDepotBase StackDepot; static StackDepot theDepot; -// Keep rarely accessed stack traces out of frequently access nodes to improve -// caching efficiency. -static TwoLevelMap - storeIds; // Keep mutable data out of frequently access nodes to improve caching // efficiency. static TwoLevelMapAtExitStack.PopBack(); } - Acquire(cur_thread(), (uptr)0, (uptr)ctx); + ThreadState *thr = cur_thread(); + Acquire(thr, ctx->pc, (uptr)ctx); + FuncEntry(thr, ctx->pc); ((void(*)())ctx->f)(); + FuncExit(thr); Free(ctx); } -static void cxa_at_exit_wrapper(void *arg) { - Acquire(cur_thread(), 0, (uptr)arg); +static void cxa_at_exit_callback_installed_at(void *arg) { + ThreadState *thr = cur_thread(); AtExitCtx *ctx = (AtExitCtx*)arg; + Acquire(thr, ctx->pc, (uptr)arg); + FuncEntry(thr, ctx->pc); ((void(*)(void *arg))ctx->f)(ctx->arg); + FuncExit(thr); Free(ctx); } @@ -406,7 +416,7 @@ TSAN_INTERCEPTOR(int, atexit, void (*f)()) { // We want to setup the atexit callback even if we are in ignored lib // or after fork. SCOPED_INTERCEPTOR_RAW(atexit, f); - return setup_at_exit_wrapper(thr, pc, (void(*)())f, 0, 0); + return setup_at_exit_wrapper(thr, GET_CALLER_PC(), (void (*)())f, 0, 0); } #endif @@ -414,7 +424,7 @@ TSAN_INTERCEPTOR(int, __cxa_atexit, void (*f)(void *a), void *arg, void *dso) { if (in_symbolizer()) return 0; SCOPED_TSAN_INTERCEPTOR(__cxa_atexit, f, arg, dso); - return setup_at_exit_wrapper(thr, pc, (void(*)())f, arg, dso); + return setup_at_exit_wrapper(thr, GET_CALLER_PC(), (void (*)())f, arg, dso); } static int setup_at_exit_wrapper(ThreadState *thr, uptr pc, void(*f)(), @@ -422,6 +432,7 @@ static int setup_at_exit_wrapper(ThreadState *thr, uptr pc, void(*f)(), auto *ctx = New(); ctx->f = f; ctx->arg = arg; + ctx->pc = pc; Release(thr, pc, (uptr)ctx); // Memory allocation in __cxa_atexit will race with free during exit, // because we do not see synchronization around atexit callback list. @@ -437,25 +448,27 @@ static int setup_at_exit_wrapper(ThreadState *thr, uptr pc, void(*f)(), // due to atexit_mu held on exit from the calloc interceptor. ScopedIgnoreInterceptors ignore; - res = REAL(__cxa_atexit)((void (*)(void *a))at_exit_wrapper, 0, 0); + res = REAL(__cxa_atexit)((void (*)(void *a))at_exit_callback_installed_at, + 0, 0); // Push AtExitCtx on the top of the stack of callback functions if (!res) { interceptor_ctx()->AtExitStack.PushBack(ctx); } } else { - res = REAL(__cxa_atexit)(cxa_at_exit_wrapper, ctx, dso); + res = REAL(__cxa_atexit)(cxa_at_exit_callback_installed_at, ctx, dso); } ThreadIgnoreEnd(thr); return res; } #if !SANITIZER_MAC && !SANITIZER_NETBSD -static void on_exit_wrapper(int status, void *arg) { +static void on_exit_callback_installed_at(int status, void *arg) { ThreadState *thr = cur_thread(); - uptr pc = 0; - Acquire(thr, pc, (uptr)arg); AtExitCtx *ctx = (AtExitCtx*)arg; + Acquire(thr, ctx->pc, (uptr)arg); + FuncEntry(thr, ctx->pc); ((void(*)(int status, void *arg))ctx->f)(status, ctx->arg); + FuncExit(thr); Free(ctx); } @@ -466,11 +479,12 @@ TSAN_INTERCEPTOR(int, on_exit, void(*f)(int, void*), void *arg) { auto *ctx = New(); ctx->f = (void(*)())f; ctx->arg = arg; + ctx->pc = GET_CALLER_PC(); Release(thr, pc, (uptr)ctx); // Memory allocation in __cxa_atexit will race with free during exit, // because we do not see synchronization around atexit callback list. ThreadIgnoreBegin(thr, pc); - int res = REAL(on_exit)(on_exit_wrapper, ctx); + int res = REAL(on_exit)(on_exit_callback_installed_at, ctx); ThreadIgnoreEnd(thr); return res; } @@ -2368,6 +2382,15 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc, if (fd >= 0) FdClose(thr, pc, fd); \ } +#define COMMON_INTERCEPTOR_DLOPEN(filename, flag) \ + ({ \ + CheckNoDeepBind(filename, flag); \ + ThreadIgnoreBegin(thr, 0); \ + void *res = REAL(dlopen)(filename, flag); \ + ThreadIgnoreEnd(thr); \ + res; \ + }) + #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \ libignore()->OnLibraryLoaded(filename) diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.cpp index ef97ad0bc94e..a31bebcb6ba9 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.cpp @@ -69,8 +69,17 @@ Allocator *allocator() { struct GlobalProc { Mutex mtx; Processor *proc; + // This mutex represents the internal allocator combined for + // the purposes of deadlock detection. The internal allocator + // uses multiple mutexes, moreover they are locked only occasionally + // and they are spin mutexes which don't support deadlock detection. + // So we use this fake mutex to serve as a substitute for these mutexes. + CheckedMutex internal_alloc_mtx; - GlobalProc() : mtx(MutexTypeGlobalProc), proc(ProcCreate()) {} + GlobalProc() + : mtx(MutexTypeGlobalProc), + proc(ProcCreate()), + internal_alloc_mtx(MutexTypeInternalAlloc) {} }; static char global_proc_placeholder[sizeof(GlobalProc)] ALIGNED(64); @@ -78,6 +87,11 @@ GlobalProc *global_proc() { return reinterpret_cast(&global_proc_placeholder); } +static void InternalAllocAccess() { + global_proc()->internal_alloc_mtx.Lock(); + global_proc()->internal_alloc_mtx.Unlock(); +} + ScopedGlobalProcessor::ScopedGlobalProcessor() { GlobalProc *gp = global_proc(); ThreadState *thr = cur_thread(); @@ -110,6 +124,18 @@ ScopedGlobalProcessor::~ScopedGlobalProcessor() { gp->mtx.Unlock(); } +void AllocatorLock() NO_THREAD_SAFETY_ANALYSIS { + global_proc()->mtx.Lock(); + global_proc()->internal_alloc_mtx.Lock(); + InternalAllocatorLock(); +} + +void AllocatorUnlock() NO_THREAD_SAFETY_ANALYSIS { + InternalAllocatorUnlock(); + global_proc()->internal_alloc_mtx.Unlock(); + global_proc()->mtx.Unlock(); +} + static constexpr uptr kMaxAllowedMallocSize = 1ull << 40; static uptr max_user_defined_malloc_size; @@ -342,6 +368,7 @@ void *Alloc(uptr sz) { thr->nomalloc = 0; // CHECK calls internal_malloc(). CHECK(0); } + InternalAllocAccess(); return InternalAlloc(sz, &thr->proc()->internal_alloc_cache); } @@ -351,6 +378,7 @@ void FreeImpl(void *p) { thr->nomalloc = 0; // CHECK calls internal_malloc(). CHECK(0); } + InternalAllocAccess(); InternalFree(p, &thr->proc()->internal_alloc_cache); } diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.h b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.h index efea5e5abdec..db8488eabbe2 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.h +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.h @@ -24,6 +24,8 @@ void ReplaceSystemMalloc(); void AllocatorProcStart(Processor *proc); void AllocatorProcFinish(Processor *proc); void AllocatorPrintStats(); +void AllocatorLock(); +void AllocatorUnlock(); // For user allocations. void *user_alloc_internal(ThreadState *thr, uptr pc, uptr sz, diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp index 3faa2d0c6192..1465f9953c19 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp @@ -25,6 +25,7 @@ #include "tsan_rtl.h" #include "tsan_flags.h" +#include #include #include #include @@ -45,70 +46,83 @@ namespace __tsan { #if !SANITIZER_GO -static void *SignalSafeGetOrAllocate(uptr *dst, uptr size) { - atomic_uintptr_t *a = (atomic_uintptr_t *)dst; - void *val = (void *)atomic_load_relaxed(a); - atomic_signal_fence(memory_order_acquire); // Turns the previous load into - // acquire wrt signals. - if (UNLIKELY(val == nullptr)) { - val = (void *)internal_mmap(nullptr, size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); - CHECK(val); - void *cmp = nullptr; - if (!atomic_compare_exchange_strong(a, (uintptr_t *)&cmp, (uintptr_t)val, - memory_order_acq_rel)) { - internal_munmap(val, size); - val = cmp; - } - } - return val; +static char main_thread_state[sizeof(ThreadState)] ALIGNED( + SANITIZER_CACHE_LINE_SIZE); +static ThreadState *dead_thread_state; +static pthread_key_t thread_state_key; + +// We rely on the following documented, but Darwin-specific behavior to keep the +// reference to the ThreadState object alive in TLS: +// pthread_key_create man page: +// If, after all the destructors have been called for all non-NULL values with +// associated destructors, there are still some non-NULL values with +// associated destructors, then the process is repeated. If, after at least +// [PTHREAD_DESTRUCTOR_ITERATIONS] iterations of destructor calls for +// outstanding non-NULL values, there are still some non-NULL values with +// associated destructors, the implementation stops calling destructors. +static_assert(PTHREAD_DESTRUCTOR_ITERATIONS == 4, "Small number of iterations"); +static void ThreadStateDestructor(void *thr) { + int res = pthread_setspecific(thread_state_key, thr); + CHECK_EQ(res, 0); } -// On OS X, accessing TLVs via __thread or manually by using pthread_key_* is -// problematic, because there are several places where interceptors are called -// when TLVs are not accessible (early process startup, thread cleanup, ...). -// The following provides a "poor man's TLV" implementation, where we use the -// shadow memory of the pointer returned by pthread_self() to store a pointer to -// the ThreadState object. The main thread's ThreadState is stored separately -// in a static variable, because we need to access it even before the -// shadow memory is set up. -static uptr main_thread_identity = 0; -ALIGNED(64) static char main_thread_state[sizeof(ThreadState)]; -static ThreadState *main_thread_state_loc = (ThreadState *)main_thread_state; +static void InitializeThreadStateStorage() { + int res; + CHECK_EQ(thread_state_key, 0); + res = pthread_key_create(&thread_state_key, ThreadStateDestructor); + CHECK_EQ(res, 0); + res = pthread_setspecific(thread_state_key, main_thread_state); + CHECK_EQ(res, 0); -// We cannot use pthread_self() before libpthread has been initialized. Our -// current heuristic for guarding this is checking `main_thread_identity` which -// is only assigned in `__tsan::InitializePlatform`. -static ThreadState **cur_thread_location() { - if (main_thread_identity == 0) - return &main_thread_state_loc; - uptr thread_identity = (uptr)pthread_self(); - if (thread_identity == main_thread_identity) - return &main_thread_state_loc; - return (ThreadState **)MemToShadow(thread_identity); + auto dts = (ThreadState *)MmapOrDie(sizeof(ThreadState), "ThreadState"); + dts->fast_state.SetIgnoreBit(); + dts->ignore_interceptors = 1; + dts->is_dead = true; + const_cast(dts->tid) = kInvalidTid; + res = internal_mprotect(dts, sizeof(ThreadState), PROT_READ); // immutable + CHECK_EQ(res, 0); + dead_thread_state = dts; } ThreadState *cur_thread() { - return (ThreadState *)SignalSafeGetOrAllocate( - (uptr *)cur_thread_location(), sizeof(ThreadState)); + // Some interceptors get called before libpthread has been initialized and in + // these cases we must avoid calling any pthread APIs. + if (UNLIKELY(!thread_state_key)) { + return (ThreadState *)main_thread_state; + } + + // We only reach this line after InitializeThreadStateStorage() ran, i.e, + // after TSan (and therefore libpthread) have been initialized. + ThreadState *thr = (ThreadState *)pthread_getspecific(thread_state_key); + if (UNLIKELY(!thr)) { + thr = (ThreadState *)MmapOrDie(sizeof(ThreadState), "ThreadState"); + int res = pthread_setspecific(thread_state_key, thr); + CHECK_EQ(res, 0); + } + return thr; } void set_cur_thread(ThreadState *thr) { - *cur_thread_location() = thr; + int res = pthread_setspecific(thread_state_key, thr); + CHECK_EQ(res, 0); } -// TODO(kuba.brecka): This is not async-signal-safe. In particular, we call -// munmap first and then clear `fake_tls`; if we receive a signal in between, -// handler will try to access the unmapped ThreadState. void cur_thread_finalize() { - ThreadState **thr_state_loc = cur_thread_location(); - if (thr_state_loc == &main_thread_state_loc) { + ThreadState *thr = (ThreadState *)pthread_getspecific(thread_state_key); + CHECK(thr); + if (thr == (ThreadState *)main_thread_state) { // Calling dispatch_main() or xpc_main() actually invokes pthread_exit to // exit the main thread. Let's keep the main thread's ThreadState. return; } - internal_munmap(*thr_state_loc, sizeof(ThreadState)); - *thr_state_loc = nullptr; + // Intercepted functions can still get called after cur_thread_finalize() + // (called from DestroyThreadState()), so put a fake thread state for "dead" + // threads. An alternative solution would be to release the ThreadState + // object from THREAD_DESTROY (which is delivered later and on the parent + // thread) instead of THREAD_TERMINATE. + int res = pthread_setspecific(thread_state_key, dead_thread_state); + CHECK_EQ(res, 0); + UnmapOrDie(thr, sizeof(ThreadState)); } #endif @@ -222,11 +236,10 @@ static void my_pthread_introspection_hook(unsigned int event, pthread_t thread, ThreadStart(thr, tid, GetTid(), ThreadType::Worker); } } else if (event == PTHREAD_INTROSPECTION_THREAD_TERMINATE) { - if (thread == pthread_self()) { - ThreadState *thr = cur_thread(); - if (thr->tctx) { - DestroyThreadState(); - } + CHECK_EQ(thread, pthread_self()); + ThreadState *thr = cur_thread(); + if (thr->tctx) { + DestroyThreadState(); } } @@ -253,8 +266,7 @@ void InitializePlatform() { #if !SANITIZER_GO CheckAndProtect(); - CHECK_EQ(main_thread_identity, 0); - main_thread_identity = (uptr)pthread_self(); + InitializeThreadStateStorage(); prev_pthread_introspection_hook = pthread_introspection_hook_install(&my_pthread_introspection_hook); @@ -286,24 +298,11 @@ uptr ExtractLongJmpSp(uptr *env) { extern "C" void __tsan_tls_initialization() {} void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) { - // The pointer to the ThreadState object is stored in the shadow memory - // of the tls. - uptr tls_end = tls_addr + tls_size; - uptr thread_identity = (uptr)pthread_self(); const uptr pc = StackTrace::GetNextInstructionPc( reinterpret_cast(__tsan_tls_initialization)); - if (thread_identity == main_thread_identity) { - MemoryRangeImitateWrite(thr, pc, tls_addr, tls_size); - } else { - uptr thr_state_start = thread_identity; - uptr thr_state_end = thr_state_start + sizeof(uptr); - CHECK_GE(thr_state_start, tls_addr); - CHECK_LE(thr_state_start, tls_addr + tls_size); - CHECK_GE(thr_state_end, tls_addr); - CHECK_LE(thr_state_end, tls_addr + tls_size); - MemoryRangeImitateWrite(thr, pc, tls_addr, thr_state_start - tls_addr); - MemoryRangeImitateWrite(thr, pc, thr_state_end, tls_end - thr_state_end); - } + // Unlike Linux, we only store a pointer to the ThreadState object in TLS; + // just mark the entire range as written to. + MemoryRangeImitateWrite(thr, pc, tls_addr, tls_size); } #endif diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp index ff7726ef0608..c14af9788e32 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp @@ -34,6 +34,9 @@ extern "C" void __tsan_resume() { __tsan_resumed = 1; } +SANITIZER_WEAK_DEFAULT_IMPL +void __tsan_test_only_on_fork() {} + namespace __tsan { #if !SANITIZER_GO @@ -271,8 +274,39 @@ void DontNeedShadowFor(uptr addr, uptr size) { } #if !SANITIZER_GO +// We call UnmapShadow before the actual munmap, at that point we don't yet +// know if the provided address/size are sane. We can't call UnmapShadow +// after the actual munmap becuase at that point the memory range can +// already be reused for something else, so we can't rely on the munmap +// return value to understand is the values are sane. +// While calling munmap with insane values (non-canonical address, negative +// size, etc) is an error, the kernel won't crash. We must also try to not +// crash as the failure mode is very confusing (paging fault inside of the +// runtime on some derived shadow address). +static bool IsValidMmapRange(uptr addr, uptr size) { + if (size == 0) + return true; + if (static_cast(size) < 0) + return false; + if (!IsAppMem(addr) || !IsAppMem(addr + size - 1)) + return false; + // Check that if the start of the region belongs to one of app ranges, + // end of the region belongs to the same region. + const uptr ranges[][2] = { + {LoAppMemBeg(), LoAppMemEnd()}, + {MidAppMemBeg(), MidAppMemEnd()}, + {HiAppMemBeg(), HiAppMemEnd()}, + }; + for (auto range : ranges) { + if (addr >= range[0] && addr < range[1]) + return addr + size <= range[1]; + } + return false; +} + void UnmapShadow(ThreadState *thr, uptr addr, uptr size) { - if (size == 0) return; + if (size == 0 || !IsValidMmapRange(addr, size)) + return; DontNeedShadowFor(addr, size); ScopedGlobalProcessor sgp; ctx->metamap.ResetRange(thr->proc(), addr, size); @@ -491,6 +525,7 @@ void ForkBefore(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS { ctx->thread_registry.Lock(); ctx->report_mtx.Lock(); ScopedErrorReportLock::Lock(); + AllocatorLock(); // Suppress all reports in the pthread_atfork callbacks. // Reports will deadlock on the report_mtx. // We could ignore sync operations as well, @@ -499,12 +534,20 @@ void ForkBefore(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS { thr->suppress_reports++; // On OS X, REAL(fork) can call intercepted functions (OSSpinLockLock), and // we'll assert in CheckNoLocks() unless we ignore interceptors. + // On OS X libSystem_atfork_prepare/parent/child callbacks are called + // after/before our callbacks and they call free. thr->ignore_interceptors++; + // Disables memory write in OnUserAlloc/Free. + thr->ignore_reads_and_writes++; + + __tsan_test_only_on_fork(); } void ForkParentAfter(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS { thr->suppress_reports--; // Enabled in ForkBefore. thr->ignore_interceptors--; + thr->ignore_reads_and_writes--; + AllocatorUnlock(); ScopedErrorReportLock::Unlock(); ctx->report_mtx.Unlock(); ctx->thread_registry.Unlock(); @@ -514,6 +557,8 @@ void ForkChildAfter(ThreadState *thr, uptr pc, bool start_thread) NO_THREAD_SAFETY_ANALYSIS { thr->suppress_reports--; // Enabled in ForkBefore. thr->ignore_interceptors--; + thr->ignore_reads_and_writes--; + AllocatorUnlock(); ScopedErrorReportLock::Unlock(); ctx->report_mtx.Unlock(); ctx->thread_registry.Unlock(); @@ -747,14 +792,17 @@ using namespace __tsan; MutexMeta mutex_meta[] = { {MutexInvalid, "Invalid", {}}, {MutexThreadRegistry, "ThreadRegistry", {}}, - {MutexTypeTrace, "Trace", {MutexLeaf}}, - {MutexTypeReport, "Report", {MutexTypeSyncVar}}, - {MutexTypeSyncVar, "SyncVar", {}}, + {MutexTypeTrace, "Trace", {}}, + {MutexTypeReport, + "Report", + {MutexTypeSyncVar, MutexTypeGlobalProc, MutexTypeTrace}}, + {MutexTypeSyncVar, "SyncVar", {MutexTypeTrace}}, {MutexTypeAnnotations, "Annotations", {}}, {MutexTypeAtExit, "AtExit", {MutexTypeSyncVar}}, {MutexTypeFired, "Fired", {MutexLeaf}}, {MutexTypeRacy, "Racy", {MutexLeaf}}, {MutexTypeGlobalProc, "GlobalProc", {}}, + {MutexTypeInternalAlloc, "InternalAlloc", {MutexLeaf}}, {}, }; diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp index 811695d144c5..f332a6a8d1d8 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp @@ -346,7 +346,7 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) { ThreadContext *tctx = FindThreadByTidLocked(b->tid); auto *loc = New(); loc->type = ReportLocationHeap; - loc->heap_chunk_start = (uptr)allocator()->GetBlockBegin((void *)addr); + loc->heap_chunk_start = block_begin; loc->heap_chunk_size = b->siz; loc->external_tag = b->tag; loc->tid = tctx ? tctx->tid : b->tid; diff --git a/contrib/llvm-project/libcxx/CREDITS.TXT b/contrib/llvm-project/libcxx/CREDITS.TXT index 597c5fcb7cf4..fc442f4db1a1 100644 --- a/contrib/llvm-project/libcxx/CREDITS.TXT +++ b/contrib/llvm-project/libcxx/CREDITS.TXT @@ -149,6 +149,10 @@ N: Klaas de Vries E: klaas at klaasgaaf dot nl D: Minor bug fix. +N: Mark de Wever +E: koraq at xs4all dot nl +D: Format library support. + N: Zhang Xiongpang E: zhangxiongpang@gmail.com D: Minor patches and bug fixes. diff --git a/contrib/llvm-project/libcxx/include/__bit/byteswap.h b/contrib/llvm-project/libcxx/include/__bit/byteswap.h new file mode 100644 index 000000000000..970074ed98ce --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__bit/byteswap.h @@ -0,0 +1,55 @@ +// -*- 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___BIT_BYTESWAP_H +#define _LIBCPP___BIT_BYTESWAP_H + +#include <__concepts/arithmetic.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template +_LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept { + + if constexpr (sizeof(_Tp) == 1) { + return __val; + } else if constexpr (sizeof(_Tp) == 2) { + return __builtin_bswap16(__val); + } else if constexpr (sizeof(_Tp) == 4) { + return __builtin_bswap32(__val); + } else if constexpr (sizeof(_Tp) == 8) { + return __builtin_bswap64(__val); +#ifndef _LIBCPP_HAS_NO_INT128 + } else if constexpr (sizeof(_Tp) == 16) { +#if __has_builtin(__builtin_bswap128) + return __builtin_bswap128(__val); +#else + return static_cast<_Tp>(byteswap(static_cast(__val))) << 64 | + static_cast<_Tp>(byteswap(static_cast(__val >> 64))); +#endif // __has_builtin(__builtin_bswap128) +#endif // _LIBCPP_HAS_NO_INT128 + } else { + static_assert(sizeof(_Tp) == 0, "byteswap is unimplemented for integral types of this size"); + } +} + +#endif // _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_BYTESWAP_H diff --git a/contrib/llvm-project/libcxx/include/__bsd_locale_fallbacks.h b/contrib/llvm-project/libcxx/include/__bsd_locale_fallbacks.h index 2d5c2eca4679..a5788d9777b5 100644 --- a/contrib/llvm-project/libcxx/include/__bsd_locale_fallbacks.h +++ b/contrib/llvm-project/libcxx/include/__bsd_locale_fallbacks.h @@ -108,7 +108,7 @@ size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, } #endif -inline +inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __libcpp_snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -118,7 +118,7 @@ int __libcpp_snprintf_l(char *__s, size_t __n, locale_t __l, const char *__forma return __res; } -inline +inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __libcpp_asprintf_l(char **__s, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -128,7 +128,7 @@ int __libcpp_asprintf_l(char **__s, locale_t __l, const char *__format, ...) { return __res; } -inline +inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __libcpp_sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); diff --git a/contrib/llvm-project/libcxx/include/__compare/partial_order.h b/contrib/llvm-project/libcxx/include/__compare/partial_order.h new file mode 100644 index 000000000000..ac8b405a4090 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__compare/partial_order.h @@ -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___COMPARE_PARTIAL_ORDER +#define _LIBCPP___COMPARE_PARTIAL_ORDER + +#include <__compare/compare_three_way.h> +#include <__compare/ordering.h> +#include <__compare/weak_order.h> +#include <__config> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> +#include + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [cmp.alg] +namespace __partial_order { + struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) + noexcept(noexcept(partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(partial_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( partial_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return partial_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(partial_ordering(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( partial_ordering(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return partial_ordering(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()); } + }; +} // namespace __partial_order + +inline namespace __cpo { + inline constexpr auto partial_order = __partial_order::__fn{}; +} // namespace __cpo + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_PARTIAL_ORDER diff --git a/contrib/llvm-project/libcxx/include/__compare/strong_order.h b/contrib/llvm-project/libcxx/include/__compare/strong_order.h new file mode 100644 index 000000000000..e49b2d45de45 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__compare/strong_order.h @@ -0,0 +1,136 @@ +//===----------------------------------------------------------------------===// +// +// 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___COMPARE_STRONG_ORDER +#define _LIBCPP___COMPARE_STRONG_ORDER + +#include <__bit/bit_cast.h> +#include <__compare/compare_three_way.h> +#include <__compare/ordering.h> +#include <__config> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> +#include +#include +#include +#include + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [cmp.alg] +namespace __strong_order { + struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) + noexcept(noexcept(strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template> + requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> + _LIBCPP_HIDE_FROM_ABI static constexpr strong_ordering + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept + { + if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int32_t)) { + int32_t __rx = _VSTD::bit_cast(__t); + int32_t __ry = _VSTD::bit_cast(__u); + __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; + __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; + return (__rx <=> __ry); + } else if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int64_t)) { + int64_t __rx = _VSTD::bit_cast(__t); + int64_t __ry = _VSTD::bit_cast(__u); + __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; + __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; + return (__rx <=> __ry); + } else if (__t < __u) { + return strong_ordering::less; + } else if (__t > __u) { + return strong_ordering::greater; + } else if (__t == __u) { + if constexpr (numeric_limits<_Dp>::radix == 2) { + return _VSTD::signbit(__u) <=> _VSTD::signbit(__t); + } else { + // This is bullet 3 of the IEEE754 algorithm, relevant + // only for decimal floating-point; + // see https://stackoverflow.com/questions/69068075/ + if (__t == 0 || _VSTD::isinf(__t)) { + return _VSTD::signbit(__u) <=> _VSTD::signbit(__t); + } else { + int __texp, __uexp; + (void)_VSTD::frexp(__t, &__texp); + (void)_VSTD::frexp(__u, &__uexp); + return (__t < 0) ? (__texp <=> __uexp) : (__uexp <=> __texp); + } + } + } else { + // They're unordered, so one of them must be a NAN. + // The order is -QNAN, -SNAN, numbers, +SNAN, +QNAN. + bool __t_is_nan = _VSTD::isnan(__t); + bool __u_is_nan = _VSTD::isnan(__u); + bool __t_is_negative = _VSTD::signbit(__t); + bool __u_is_negative = _VSTD::signbit(__u); + using _IntType = std::conditional_t< + sizeof(__t) == sizeof(int32_t), int32_t, std::conditional_t< + sizeof(__t) == sizeof(int64_t), int64_t, void> + >; + if constexpr (std::is_same_v<_IntType, void>) { + static_assert(sizeof(_Dp) == 0, "std::strong_order is unimplemented for this floating-point type"); + } else if (__t_is_nan && __u_is_nan) { + // Order by sign bit, then by "payload bits" (we'll just use bit_cast). + if (__t_is_negative != __u_is_negative) { + return (__u_is_negative <=> __t_is_negative); + } else { + return _VSTD::bit_cast<_IntType>(__t) <=> _VSTD::bit_cast<_IntType>(__u); + } + } else if (__t_is_nan) { + return __t_is_negative ? strong_ordering::less : strong_ordering::greater; + } else { + return __u_is_negative ? strong_ordering::greater : strong_ordering::less; + } + } + } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(strong_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( strong_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return strong_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()); } + }; +} // namespace __strong_order + +inline namespace __cpo { + inline constexpr auto strong_order = __strong_order::__fn{}; +} // namespace __cpo + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___COMPARE_STRONG_ORDER diff --git a/contrib/llvm-project/libcxx/include/__compare/weak_order.h b/contrib/llvm-project/libcxx/include/__compare/weak_order.h new file mode 100644 index 000000000000..f67416ed3ebe --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__compare/weak_order.h @@ -0,0 +1,100 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_WEAK_ORDER +#define _LIBCPP___COMPARE_WEAK_ORDER + +#include <__compare/compare_three_way.h> +#include <__compare/ordering.h> +#include <__compare/strong_order.h> +#include <__config> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> +#include +#include + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [cmp.alg] +namespace __weak_order { + struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<3>) + noexcept(noexcept(weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template> + requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> + _LIBCPP_HIDE_FROM_ABI static constexpr weak_ordering + __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) noexcept + { + std::partial_ordering __po = (__t <=> __u); + if (__po == std::partial_ordering::less) { + return std::weak_ordering::less; + } else if (__po == std::partial_ordering::equivalent) { + return std::weak_ordering::equivalent; + } else if (__po == std::partial_ordering::greater) { + return std::weak_ordering::greater; + } else { + // Otherwise, at least one of them is a NaN. + bool __t_is_nan = _VSTD::isnan(__t); + bool __u_is_nan = _VSTD::isnan(__u); + bool __t_is_negative = _VSTD::signbit(__t); + bool __u_is_negative = _VSTD::signbit(__u); + if (__t_is_nan && __u_is_nan) { + return (__u_is_negative <=> __t_is_negative); + } else if (__t_is_nan) { + return __t_is_negative ? weak_ordering::less : weak_ordering::greater; + } else { + return __u_is_negative ? weak_ordering::greater : weak_ordering::less; + } + } + } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(weak_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( weak_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return weak_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(weak_ordering(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( weak_ordering(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return weak_ordering(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<3>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<3>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<3>()); } + }; +} // namespace __weak_order + +inline namespace __cpo { + inline constexpr auto weak_order = __weak_order::__fn{}; +} // namespace __cpo + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_WEAK_ORDER diff --git a/contrib/llvm-project/libcxx/include/__config b/contrib/llvm-project/libcxx/include/__config index dbf4383cd6e3..da03e877f753 100644 --- a/contrib/llvm-project/libcxx/include/__config +++ b/contrib/llvm-project/libcxx/include/__config @@ -74,10 +74,6 @@ # define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB # define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB # define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE -// Don't use a nullptr_t simulation type in C++03 instead using C++11 nullptr -// provided under the alternate keyword __nullptr, which changes the mangling -// of nullptr_t. This option is ABI incompatible with GCC in C++03 mode. -# define _LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR // Define a key function for `bad_function_call` in the library, to centralize // its vtable and typeinfo to libc++ rather than having all other libraries // using that class define their own copies. @@ -127,6 +123,23 @@ # endif #endif +// By default, don't use a nullptr_t emulation type in C++03. +// +// This is technically an ABI break from previous releases, however it is +// very unlikely to impact anyone. If a user is impacted by this break, +// they can return to using the C++03 nullptr emulation by defining +// _LIBCPP_ABI_USE_CXX03_NULLPTR_EMULATION. +// +// This switch will be removed entirely in favour of never providing a +// C++03 emulation after one release. +// +// IMPORTANT: IF YOU ARE READING THIS AND YOU TURN THIS MACRO ON, PLEASE LEAVE +// A COMMENT ON https://reviews.llvm.org/D109459 OR YOU WILL BE BROKEN +// IN THE FUTURE WHEN WE REMOVE THE ABILITY TO USE THE C++03 EMULATION. +#ifndef _LIBCPP_ABI_USE_CXX03_NULLPTR_EMULATION +# define _LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR +#endif + #if defined(_LIBCPP_BUILDING_LIBRARY) || defined(_LIBCPP_ABI_UNSTABLE) || _LIBCPP_ABI_VERSION >= 2 // Enable additional explicit instantiations of iostreams components. This // reduces the number of weak definitions generated in programs that use @@ -1056,12 +1069,6 @@ typedef unsigned int char32_t; # define _LIBCPP_NODISCARD_AFTER_CXX17 #endif -#if !defined(_LIBCPP_DEBUG) && _LIBCPP_STD_VER > 11 -# define _LIBCPP_CONSTEXPR_IF_NODEBUG constexpr -#else -# define _LIBCPP_CONSTEXPR_IF_NODEBUG -#endif - #if __has_attribute(no_destroy) # define _LIBCPP_NO_DESTROY __attribute__((__no_destroy__)) #else @@ -1376,10 +1383,12 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container( #endif #if defined(__GNUC__) || defined(__clang__) -#define _LIBCPP_FORMAT_PRINTF(a, b) \ - __attribute__((__format__(__printf__, a, b))) + // The attribute uses 1-based indices for ordinary and static member functions. + // The attribute uses 2-based indices for non-static member functions. +# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) \ + __attribute__((__format__(archetype, format_string_index, first_format_arg_index))) #else -#define _LIBCPP_FORMAT_PRINTF(a, b) +# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) /* nothing */ #endif #endif // __cplusplus diff --git a/contrib/llvm-project/libcxx/include/__iterator/reverse_iterator.h b/contrib/llvm-project/libcxx/include/__iterator/reverse_iterator.h index f7a948950df2..d06859ee5f39 100644 --- a/contrib/llvm-project/libcxx/include/__iterator/reverse_iterator.h +++ b/contrib/llvm-project/libcxx/include/__iterator/reverse_iterator.h @@ -11,6 +11,8 @@ #define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H #include <__config> +#include <__compare/compare_three_way_result.h> +#include <__compare/three_way_comparable.h> #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> #include <__memory/addressof.h> @@ -193,6 +195,16 @@ operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& return __x.base() >= __y.base(); } +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) +template _Iter2> +_LIBCPP_HIDE_FROM_ABI constexpr +compare_three_way_result_t<_Iter1, _Iter2> +operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __y.base() <=> __x.base(); +} +#endif + #ifndef _LIBCPP_CXX03_LANG template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 diff --git a/contrib/llvm-project/libcxx/include/__iterator/wrap_iter.h b/contrib/llvm-project/libcxx/include/__iterator/wrap_iter.h index 28872f9fa41a..cfcc9857b3fc 100644 --- a/contrib/llvm-project/libcxx/include/__iterator/wrap_iter.h +++ b/contrib/llvm-project/libcxx/include/__iterator/wrap_iter.h @@ -40,120 +40,129 @@ class __wrap_iter private: iterator_type __i; public: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter() _NOEXCEPT -#if _LIBCPP_STD_VER > 11 - : __i{} -#endif + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter() _NOEXCEPT + : __i() { #if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) __get_db()->__insert_i(this); #endif } - template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG + template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter(const __wrap_iter<_Up>& __u, typename enable_if::value>::type* = nullptr) _NOEXCEPT : __i(__u.base()) { #if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) __get_db()->__iterator_copy(this, _VSTD::addressof(__u)); #endif } #if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter(const __wrap_iter& __x) : __i(__x.base()) { + if (!__libcpp_is_constant_evaluated()) __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator=(const __wrap_iter& __x) { - if (this != _VSTD::addressof(__x)) + if (this != _VSTD::addressof(__x) && !__libcpp_is_constant_evaluated()) { __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); __i = __x.__i; } return *this; } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 ~__wrap_iter() { + if (!__libcpp_is_constant_evaluated()) __get_db()->__erase_i(this); } #endif - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator*() const _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 reference operator*() const _NOEXCEPT { #if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to dereference a non-dereferenceable iterator"); #endif return *__i; } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG pointer operator->() const _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 pointer operator->() const _NOEXCEPT { #if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to dereference a non-dereferenceable iterator"); #endif return _VSTD::__to_address(__i); } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator++() _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator++() _NOEXCEPT { #if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to increment a non-incrementable iterator"); #endif ++__i; return *this; } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator++(int) _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter operator++(int) _NOEXCEPT {__wrap_iter __tmp(*this); ++(*this); return __tmp;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator--() _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator--() _NOEXCEPT { #if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), "Attempted to decrement a non-decrementable iterator"); #endif --__i; return *this; } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator--(int) _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter operator--(int) _NOEXCEPT {__wrap_iter __tmp(*this); --(*this); return __tmp;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator+ (difference_type __n) const _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter operator+ (difference_type __n) const _NOEXCEPT {__wrap_iter __w(*this); __w += __n; return __w;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator+=(difference_type __n) _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator+=(difference_type __n) _NOEXCEPT { #if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n), "Attempted to add/subtract an iterator outside its valid range"); #endif __i += __n; return *this; } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator- (difference_type __n) const _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter operator- (difference_type __n) const _NOEXCEPT {return *this + (-__n);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator-=(difference_type __n) _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator-=(difference_type __n) _NOEXCEPT {*this += -__n; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator[](difference_type __n) const _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 reference operator[](difference_type __n) const _NOEXCEPT { #if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n), "Attempted to subscript an iterator outside its valid range"); #endif return __i[__n]; } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG iterator_type base() const _NOEXCEPT {return __i;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 iterator_type base() const _NOEXCEPT {return __i;} private: #if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(const void* __p, iterator_type __x) : __i(__x) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter(const void* __p, iterator_type __x) : __i(__x) { + if (!__libcpp_is_constant_evaluated()) __get_db()->__insert_ic(this, __p); } #else - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {} #endif template friend class __wrap_iter; @@ -163,24 +172,25 @@ class __wrap_iter }; template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { return __x.base() == __y.base(); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { return __x.base() == __y.base(); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { #if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), "Attempted to compare incomparable iterators"); #endif @@ -188,10 +198,11 @@ bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _ } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { #if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), "Attempted to compare incomparable iterators"); #endif @@ -199,63 +210,63 @@ bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _ } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { return !(__x == __y); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { return !(__x == __y); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { return __y < __x; } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { return __y < __x; } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { return !(__x < __y); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { return !(__x < __y); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { return !(__y < __x); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { return !(__y < __x); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 #ifndef _LIBCPP_CXX03_LANG auto operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT -> decltype(__x.base() - __y.base()) @@ -265,6 +276,7 @@ operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC #endif // C++03 { #if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), "Attempted to subtract incompatible iterators"); #endif @@ -272,7 +284,7 @@ operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter<_Iter1> operator+(typename __wrap_iter<_Iter1>::difference_type __n, __wrap_iter<_Iter1> __x) _NOEXCEPT { __x += __n; diff --git a/contrib/llvm-project/libcxx/include/__memory/allocator_traits.h b/contrib/llvm-project/libcxx/include/__memory/allocator_traits.h index cc32352ae11c..f4c8fa02d650 100644 --- a/contrib/llvm-project/libcxx/include/__memory/allocator_traits.h +++ b/contrib/llvm-project/libcxx/include/__memory/allocator_traits.h @@ -349,14 +349,6 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits } }; -// A version of `allocator_traits` for internal usage that SFINAEs away if the -// given allocator doesn't have a nested `value_type`. This helps avoid hard -// errors when forming implicit deduction guides for a container that has an -// invalid Allocator type. See https://wg21.link/LWGXXXXX. -// TODO(varconst): use the actual link once available. -template -struct _LIBCPP_TEMPLATE_VIS __allocator_traits : allocator_traits<_Alloc> {}; - template struct __rebind_alloc_helper { #ifndef _LIBCPP_CXX03_LANG diff --git a/contrib/llvm-project/libcxx/include/__memory/unique_ptr.h b/contrib/llvm-project/libcxx/include/__memory/unique_ptr.h index 838960269c97..433120394269 100644 --- a/contrib/llvm-project/libcxx/include/__memory/unique_ptr.h +++ b/contrib/llvm-project/libcxx/include/__memory/unique_ptr.h @@ -174,17 +174,17 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr { template > _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {} + _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} template > _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {} + _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} template > _LIBCPP_INLINE_VISIBILITY - explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __default_init_tag()) {} + explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {} template > > @@ -226,7 +226,7 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr { typename enable_if::value && is_same<_Dp, default_delete<_Tp> >::value, __nat>::type = __nat()) _NOEXCEPT - : __ptr_(__p.release(), __default_init_tag()) {} + : __ptr_(__p.release(), __value_init_tag()) {} #endif _LIBCPP_INLINE_VISIBILITY @@ -397,19 +397,19 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> template > _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {} + _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} template > _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {} + _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} template , class = _EnableIfPointerConvertible<_Pp> > _LIBCPP_INLINE_VISIBILITY explicit unique_ptr(_Pp __p) _NOEXCEPT - : __ptr_(__p, __default_init_tag()) {} + : __ptr_(__p, __value_init_tag()) {} template >, diff --git a/contrib/llvm-project/libcxx/include/__numeric/accumulate.h b/contrib/llvm-project/libcxx/include/__numeric/accumulate.h new file mode 100644 index 000000000000..fcdad58df141 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__numeric/accumulate.h @@ -0,0 +1,52 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___NUMERIC_ACCUMULATE_H +#define _LIBCPP___NUMERIC_ACCUMULATE_H + +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_Tp +accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) +{ + for (; __first != __last; ++__first) +#if _LIBCPP_STD_VER > 17 + __init = _VSTD::move(__init) + *__first; +#else + __init = __init + *__first; +#endif + return __init; +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_Tp +accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op) +{ + for (; __first != __last; ++__first) +#if _LIBCPP_STD_VER > 17 + __init = __binary_op(_VSTD::move(__init), *__first); +#else + __init = __binary_op(__init, *__first); +#endif + return __init; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___NUMERIC_ACCUMULATE_H diff --git a/contrib/llvm-project/libcxx/include/__numeric/adjacent_difference.h b/contrib/llvm-project/libcxx/include/__numeric/adjacent_difference.h new file mode 100644 index 000000000000..5c712ecdf77d --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__numeric/adjacent_difference.h @@ -0,0 +1,72 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___NUMERIC_ADJACENT_DIFFERENCE_H +#define _LIBCPP___NUMERIC_ADJACENT_DIFFERENCE_H + +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +{ + if (__first != __last) + { + typename iterator_traits<_InputIterator>::value_type __acc(*__first); + *__result = __acc; + for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) + { + typename iterator_traits<_InputIterator>::value_type __val(*__first); +#if _LIBCPP_STD_VER > 17 + *__result = __val - _VSTD::move(__acc); +#else + *__result = __val - __acc; +#endif + __acc = _VSTD::move(__val); + } + } + return __result; +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result, + _BinaryOperation __binary_op) +{ + if (__first != __last) + { + typename iterator_traits<_InputIterator>::value_type __acc(*__first); + *__result = __acc; + for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) + { + typename iterator_traits<_InputIterator>::value_type __val(*__first); +#if _LIBCPP_STD_VER > 17 + *__result = __binary_op(__val, _VSTD::move(__acc)); +#else + *__result = __binary_op(__val, __acc); +#endif + __acc = _VSTD::move(__val); + } + } + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___NUMERIC_ADJACENT_DIFFERENCE_H diff --git a/contrib/llvm-project/libcxx/include/__numeric/exclusive_scan.h b/contrib/llvm-project/libcxx/include/__numeric/exclusive_scan.h new file mode 100644 index 000000000000..c0c89b38805d --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__numeric/exclusive_scan.h @@ -0,0 +1,53 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___NUMERIC_EXCLUSIVE_SCAN_H +#define _LIBCPP___NUMERIC_EXCLUSIVE_SCAN_H + +#include <__config> +#include <__functional/operations.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator +exclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp __init, _BinaryOp __b) { + if (__first != __last) { + _Tp __tmp(__b(__init, *__first)); + while (true) { + *__result = _VSTD::move(__init); + ++__result; + ++__first; + if (__first == __last) + break; + __init = _VSTD::move(__tmp); + __tmp = __b(__init, *__first); + } + } + return __result; +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator +exclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp __init) { + return _VSTD::exclusive_scan(__first, __last, __result, __init, _VSTD::plus<>()); +} + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___NUMERIC_EXCLUSIVE_SCAN_H diff --git a/contrib/llvm-project/libcxx/include/__numeric/gcd_lcm.h b/contrib/llvm-project/libcxx/include/__numeric/gcd_lcm.h new file mode 100644 index 000000000000..34c0e533c928 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__numeric/gcd_lcm.h @@ -0,0 +1,96 @@ +// -*- 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___NUMERIC_GCD_LCM_H +#define _LIBCPP___NUMERIC_GCD_LCM_H + +#include <__config> +#include <__debug> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +template ::value> struct __ct_abs; + +template +struct __ct_abs<_Result, _Source, true> { + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + _Result operator()(_Source __t) const noexcept + { + if (__t >= 0) return __t; + if (__t == numeric_limits<_Source>::min()) return -static_cast<_Result>(__t); + return -__t; + } +}; + +template +struct __ct_abs<_Result, _Source, false> { + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + _Result operator()(_Source __t) const noexcept { return __t; } +}; + + +template +_LIBCPP_CONSTEXPR _LIBCPP_HIDDEN +_Tp __gcd(_Tp __m, _Tp __n) +{ + static_assert((!is_signed<_Tp>::value), ""); + return __n == 0 ? __m : _VSTD::__gcd<_Tp>(__n, __m % __n); +} + +template +_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY +common_type_t<_Tp,_Up> +gcd(_Tp __m, _Up __n) +{ + static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to gcd must be integer types"); + static_assert((!is_same::type, bool>::value), "First argument to gcd cannot be bool" ); + static_assert((!is_same::type, bool>::value), "Second argument to gcd cannot be bool" ); + using _Rp = common_type_t<_Tp,_Up>; + using _Wp = make_unsigned_t<_Rp>; + return static_cast<_Rp>(_VSTD::__gcd( + static_cast<_Wp>(__ct_abs<_Rp, _Tp>()(__m)), + static_cast<_Wp>(__ct_abs<_Rp, _Up>()(__n)))); +} + +template +_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY +common_type_t<_Tp,_Up> +lcm(_Tp __m, _Up __n) +{ + static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to lcm must be integer types"); + static_assert((!is_same::type, bool>::value), "First argument to lcm cannot be bool" ); + static_assert((!is_same::type, bool>::value), "Second argument to lcm cannot be bool" ); + if (__m == 0 || __n == 0) + return 0; + + using _Rp = common_type_t<_Tp,_Up>; + _Rp __val1 = __ct_abs<_Rp, _Tp>()(__m) / _VSTD::gcd(__m, __n); + _Rp __val2 = __ct_abs<_Rp, _Up>()(__n); + _LIBCPP_ASSERT((numeric_limits<_Rp>::max() / __val1 > __val2), "Overflow in lcm"); + return __val1 * __val2; +} + +#endif // _LIBCPP_STD_VER + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___NUMERIC_GCD_LCM_H diff --git a/contrib/llvm-project/libcxx/include/__numeric/inclusive_scan.h b/contrib/llvm-project/libcxx/include/__numeric/inclusive_scan.h new file mode 100644 index 000000000000..a6b005075835 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__numeric/inclusive_scan.h @@ -0,0 +1,60 @@ +// -*- 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___NUMERIC_INCLUSIVE_SCAN_H +#define _LIBCPP___NUMERIC_INCLUSIVE_SCAN_H + +#include <__config> +#include <__functional/operations.h> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator +inclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOp __b, _Tp __init) { + for (; __first != __last; ++__first, (void)++__result) { + __init = __b(__init, *__first); + *__result = __init; + } + return __result; +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator +inclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOp __b) { + if (__first != __last) { + typename iterator_traits<_InputIterator>::value_type __init = *__first; + *__result++ = __init; + if (++__first != __last) + return _VSTD::inclusive_scan(__first, __last, __result, __b, __init); + } + + return __result; +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator inclusive_scan(_InputIterator __first, + _InputIterator __last, + _OutputIterator __result) { + return _VSTD::inclusive_scan(__first, __last, __result, _VSTD::plus<>()); +} + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___NUMERIC_INCLUSIVE_SCAN_H diff --git a/contrib/llvm-project/libcxx/include/__numeric/inner_product.h b/contrib/llvm-project/libcxx/include/__numeric/inner_product.h new file mode 100644 index 000000000000..004acdde6a0c --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__numeric/inner_product.h @@ -0,0 +1,53 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___NUMERIC_INNER_PRODUCT_H +#define _LIBCPP___NUMERIC_INNER_PRODUCT_H + +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_Tp +inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init) +{ + for (; __first1 != __last1; ++__first1, (void) ++__first2) +#if _LIBCPP_STD_VER > 17 + __init = _VSTD::move(__init) + *__first1 * *__first2; +#else + __init = __init + *__first1 * *__first2; +#endif + return __init; +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_Tp +inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, + _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) +{ + for (; __first1 != __last1; ++__first1, (void) ++__first2) +#if _LIBCPP_STD_VER > 17 + __init = __binary_op1(_VSTD::move(__init), __binary_op2(*__first1, *__first2)); +#else + __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); +#endif + return __init; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___NUMERIC_INNER_PRODUCT_H diff --git a/contrib/llvm-project/libcxx/include/__numeric/iota.h b/contrib/llvm-project/libcxx/include/__numeric/iota.h new file mode 100644 index 000000000000..b30e0e0a5484 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__numeric/iota.h @@ -0,0 +1,32 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___NUMERIC_IOTA_H +#define _LIBCPP___NUMERIC_IOTA_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value_) +{ + for (; __first != __last; ++__first, (void) ++__value_) + *__first = __value_; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___NUMERIC_IOTA_H diff --git a/contrib/llvm-project/libcxx/include/__numeric/midpoint.h b/contrib/llvm-project/libcxx/include/__numeric/midpoint.h new file mode 100644 index 000000000000..668030c46bcb --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__numeric/midpoint.h @@ -0,0 +1,85 @@ +// -*- 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___NUMERIC_MIDPOINT_H +#define _LIBCPP___NUMERIC_MIDPOINT_H + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 +template +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t && !is_same_v && !is_null_pointer_v<_Tp>, _Tp> +midpoint(_Tp __a, _Tp __b) noexcept +_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK +{ + using _Up = make_unsigned_t<_Tp>; + constexpr _Up __bitshift = numeric_limits<_Up>::digits - 1; + + _Up __diff = _Up(__b) - _Up(__a); + _Up __sign_bit = __b < __a; + + _Up __half_diff = (__diff / 2) + (__sign_bit << __bitshift) + (__sign_bit & __diff); + + return __a + __half_diff; +} + + +template +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t + && is_object_v> + && ! is_void_v> + && (sizeof(remove_pointer_t<_TPtr>) > 0), _TPtr> +midpoint(_TPtr __a, _TPtr __b) noexcept +{ + return __a + _VSTD::midpoint(ptrdiff_t(0), __b - __a); +} + + +template +constexpr int __sign(_Tp __val) { + return (_Tp(0) < __val) - (__val < _Tp(0)); +} + +template +constexpr _Fp __fp_abs(_Fp __f) { return __f >= 0 ? __f : -__f; } + +template +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t, _Fp> +midpoint(_Fp __a, _Fp __b) noexcept +{ + constexpr _Fp __lo = numeric_limits<_Fp>::min()*2; + constexpr _Fp __hi = numeric_limits<_Fp>::max()/2; + return __fp_abs(__a) <= __hi && __fp_abs(__b) <= __hi ? // typical case: overflow is impossible + (__a + __b)/2 : // always correctly rounded + __fp_abs(__a) < __lo ? __a + __b/2 : // not safe to halve a + __fp_abs(__b) < __lo ? __a/2 + __b : // not safe to halve b + __a/2 + __b/2; // otherwise correctly rounded +} + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___NUMERIC_MIDPOINT_H diff --git a/contrib/llvm-project/libcxx/include/__numeric/partial_sum.h b/contrib/llvm-project/libcxx/include/__numeric/partial_sum.h new file mode 100644 index 000000000000..9acee3afc2b0 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__numeric/partial_sum.h @@ -0,0 +1,70 @@ +// -*- 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___NUMERIC_PARTIAL_SUM_H +#define _LIBCPP___NUMERIC_PARTIAL_SUM_H + +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +{ + if (__first != __last) + { + typename iterator_traits<_InputIterator>::value_type __t(*__first); + *__result = __t; + for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) + { +#if _LIBCPP_STD_VER > 17 + __t = _VSTD::move(__t) + *__first; +#else + __t = __t + *__first; +#endif + *__result = __t; + } + } + return __result; +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result, + _BinaryOperation __binary_op) +{ + if (__first != __last) + { + typename iterator_traits<_InputIterator>::value_type __t(*__first); + *__result = __t; + for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) + { +#if _LIBCPP_STD_VER > 17 + __t = __binary_op(_VSTD::move(__t), *__first); +#else + __t = __binary_op(__t, *__first); +#endif + *__result = __t; + } + } + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___NUMERIC_PARTIAL_SUM_H diff --git a/contrib/llvm-project/libcxx/include/__numeric/reduce.h b/contrib/llvm-project/libcxx/include/__numeric/reduce.h new file mode 100644 index 000000000000..90e4d238d868 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__numeric/reduce.h @@ -0,0 +1,47 @@ +// -*- 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___NUMERIC_REDUCE_H +#define _LIBCPP___NUMERIC_REDUCE_H + +#include <__config> +#include <__functional/operations.h> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp reduce(_InputIterator __first, _InputIterator __last, + _Tp __init, _BinaryOp __b) { + for (; __first != __last; ++__first) + __init = __b(__init, *__first); + return __init; +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp reduce(_InputIterator __first, _InputIterator __last, + _Tp __init) { + return _VSTD::reduce(__first, __last, __init, _VSTD::plus<>()); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename iterator_traits<_InputIterator>::value_type +reduce(_InputIterator __first, _InputIterator __last) { + return _VSTD::reduce(__first, __last, typename iterator_traits<_InputIterator>::value_type{}); +} +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___NUMERIC_REDUCE_H diff --git a/contrib/llvm-project/libcxx/include/__numeric/transform_exclusive_scan.h b/contrib/llvm-project/libcxx/include/__numeric/transform_exclusive_scan.h new file mode 100644 index 000000000000..45b3077f6649 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__numeric/transform_exclusive_scan.h @@ -0,0 +1,49 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___NUMERIC_TRANSFORM_EXCLUSIVE_SCAN_H +#define _LIBCPP___NUMERIC_TRANSFORM_EXCLUSIVE_SCAN_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +transform_exclusive_scan(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp __init, + _BinaryOp __b, _UnaryOp __u) +{ + if (__first != __last) + { + _Tp __saved = __init; + do + { + __init = __b(__init, __u(*__first)); + *__result = __saved; + __saved = __init; + ++__result; + } while (++__first != __last); + } + return __result; +} + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___NUMERIC_TRANSFORM_EXCLUSIVE_SCAN_H diff --git a/contrib/llvm-project/libcxx/include/__numeric/transform_inclusive_scan.h b/contrib/llvm-project/libcxx/include/__numeric/transform_inclusive_scan.h new file mode 100644 index 000000000000..b0d4ab5a88fd --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__numeric/transform_inclusive_scan.h @@ -0,0 +1,58 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___NUMERIC_TRANSFORM_INCLUSIVE_SCAN_H +#define _LIBCPP___NUMERIC_TRANSFORM_INCLUSIVE_SCAN_H + +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +transform_inclusive_scan(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryOp __b, _UnaryOp __u, _Tp __init) +{ + for (; __first != __last; ++__first, (void) ++__result) { + __init = __b(__init, __u(*__first)); + *__result = __init; + } + + return __result; +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +transform_inclusive_scan(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryOp __b, _UnaryOp __u) +{ + if (__first != __last) { + typename iterator_traits<_InputIterator>::value_type __init = __u(*__first); + *__result++ = __init; + if (++__first != __last) + return _VSTD::transform_inclusive_scan(__first, __last, __result, __b, __u, __init); + } + + return __result; +} + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___NUMERIC_TRANSFORM_INCLUSIVE_SCAN_H diff --git a/contrib/llvm-project/libcxx/include/__numeric/transform_reduce.h b/contrib/llvm-project/libcxx/include/__numeric/transform_reduce.h new file mode 100644 index 000000000000..da5a77988c38 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__numeric/transform_reduce.h @@ -0,0 +1,54 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___NUMERIC_TRANSFORM_REDUCE_H +#define _LIBCPP___NUMERIC_TRANSFORM_REDUCE_H + +#include <__config> +#include <__functional/operations.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp transform_reduce(_InputIterator __first, + _InputIterator __last, _Tp __init, + _BinaryOp __b, _UnaryOp __u) { + for (; __first != __last; ++__first) + __init = __b(__init, __u(*__first)); + return __init; +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp transform_reduce(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init, + _BinaryOp1 __b1, _BinaryOp2 __b2) { + for (; __first1 != __last1; ++__first1, (void)++__first2) + __init = __b1(__init, __b2(*__first1, *__first2)); + return __init; +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp transform_reduce(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init) { + return _VSTD::transform_reduce(__first1, __last1, __first2, _VSTD::move(__init), _VSTD::plus<>(), + _VSTD::multiplies<>()); +} +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___NUMERIC_TRANSFORM_REDUCE_H diff --git a/contrib/llvm-project/libcxx/include/__random/bernoulli_distribution.h b/contrib/llvm-project/libcxx/include/__random/bernoulli_distribution.h new file mode 100644 index 000000000000..60ae5eae7033 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/bernoulli_distribution.h @@ -0,0 +1,143 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___RANDOM_BERNOULLI_DISTRIBUTION_H +#define _LIBCPP___RANDOM_BERNOULLI_DISTRIBUTION_H + +#include <__config> +#include <__random/uniform_real_distribution.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +class _LIBCPP_TEMPLATE_VIS bernoulli_distribution +{ +public: + // types + typedef bool result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + double __p_; + public: + typedef bernoulli_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(double __p = 0.5) : __p_(__p) {} + + _LIBCPP_INLINE_VISIBILITY + double p() const {return __p_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + +public: + // constructors and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + bernoulli_distribution() : bernoulli_distribution(0.5) {} + _LIBCPP_INLINE_VISIBILITY + explicit bernoulli_distribution(double __p) : __p_(param_type(__p)) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit bernoulli_distribution(double __p = 0.5) : __p_(param_type(__p)) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit bernoulli_distribution(const param_type& __p) : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template _LIBCPP_INLINE_VISIBILITY result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + _LIBCPP_INLINE_VISIBILITY + double p() const {return __p_.p();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return false;} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return true;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const bernoulli_distribution& __x, + const bernoulli_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const bernoulli_distribution& __x, + const bernoulli_distribution& __y) + {return !(__x == __y);} +}; + +template +inline +bernoulli_distribution::result_type +bernoulli_distribution::operator()(_URNG& __g, const param_type& __p) +{ + uniform_real_distribution __gen; + return __gen(__g) < __p.p(); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const bernoulli_distribution& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + return __os << __x.p(); +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, bernoulli_distribution& __x) +{ + typedef bernoulli_distribution _Eng; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + double __p; + __is >> __p; + if (!__is.fail()) + __x.param(param_type(__p)); + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_BERNOULLI_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/binomial_distribution.h b/contrib/llvm-project/libcxx/include/__random/binomial_distribution.h new file mode 100644 index 000000000000..9662de8befd9 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/binomial_distribution.h @@ -0,0 +1,225 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_BINOMIAL_DISTRIBUTION_H +#define _LIBCPP___RANDOM_BINOMIAL_DISTRIBUTION_H + +#include <__config> +#include <__random/uniform_real_distribution.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS binomial_distribution +{ +public: + // types + typedef _IntType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + result_type __t_; + double __p_; + double __pr_; + double __odds_ratio_; + result_type __r0_; + public: + typedef binomial_distribution distribution_type; + + explicit param_type(result_type __t = 1, double __p = 0.5); + + _LIBCPP_INLINE_VISIBILITY + result_type t() const {return __t_;} + _LIBCPP_INLINE_VISIBILITY + double p() const {return __p_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__t_ == __y.__t_ && __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + + friend class binomial_distribution; + }; + +private: + param_type __p_; + +public: + // constructors and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + binomial_distribution() : binomial_distribution(1) {} + _LIBCPP_INLINE_VISIBILITY + explicit binomial_distribution(result_type __t, double __p = 0.5) + : __p_(param_type(__t, __p)) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit binomial_distribution(result_type __t = 1, double __p = 0.5) + : __p_(param_type(__t, __p)) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit binomial_distribution(const param_type& __p) : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + _LIBCPP_INLINE_VISIBILITY + result_type t() const {return __p_.t();} + _LIBCPP_INLINE_VISIBILITY + double p() const {return __p_.p();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return 0;} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return t();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const binomial_distribution& __x, + const binomial_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const binomial_distribution& __x, + const binomial_distribution& __y) + {return !(__x == __y);} +}; + +#ifndef _LIBCPP_MSVCRT_LIKE +extern "C" double lgamma_r(double, int *); +#endif + +inline _LIBCPP_INLINE_VISIBILITY double __libcpp_lgamma(double __d) { +#if defined(_LIBCPP_MSVCRT_LIKE) + return lgamma(__d); +#else + int __sign; + return lgamma_r(__d, &__sign); +#endif +} + +template +binomial_distribution<_IntType>::param_type::param_type(result_type __t, double __p) + : __t_(__t), __p_(__p) +{ + if (0 < __p_ && __p_ < 1) + { + __r0_ = static_cast((__t_ + 1) * __p_); + __pr_ = _VSTD::exp(__libcpp_lgamma(__t_ + 1.) - + __libcpp_lgamma(__r0_ + 1.) - + __libcpp_lgamma(__t_ - __r0_ + 1.) + __r0_ * _VSTD::log(__p_) + + (__t_ - __r0_) * _VSTD::log(1 - __p_)); + __odds_ratio_ = __p_ / (1 - __p_); + } +} + +// Reference: Kemp, C.D. (1986). `A modal method for generating binomial +// variables', Commun. Statist. - Theor. Meth. 15(3), 805-813. +template +template +_IntType +binomial_distribution<_IntType>::operator()(_URNG& __g, const param_type& __pr) +{ + if (__pr.__t_ == 0 || __pr.__p_ == 0) + return 0; + if (__pr.__p_ == 1) + return __pr.__t_; + uniform_real_distribution __gen; + double __u = __gen(__g) - __pr.__pr_; + if (__u < 0) + return __pr.__r0_; + double __pu = __pr.__pr_; + double __pd = __pu; + result_type __ru = __pr.__r0_; + result_type __rd = __ru; + while (true) + { + bool __break = true; + if (__rd >= 1) + { + __pd *= __rd / (__pr.__odds_ratio_ * (__pr.__t_ - __rd + 1)); + __u -= __pd; + __break = false; + if (__u < 0) + return __rd - 1; + } + if ( __rd != 0 ) + --__rd; + ++__ru; + if (__ru <= __pr.__t_) + { + __pu *= (__pr.__t_ - __ru + 1) * __pr.__odds_ratio_ / __ru; + __u -= __pu; + __break = false; + if (__u < 0) + return __ru; + } + if (__break) + return 0; + } +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const binomial_distribution<_IntType>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + return __os << __x.t() << __sp << __x.p(); +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + binomial_distribution<_IntType>& __x) +{ + typedef binomial_distribution<_IntType> _Eng; + typedef typename _Eng::result_type result_type; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + result_type __t; + double __p; + __is >> __t >> __p; + if (!__is.fail()) + __x.param(param_type(__t, __p)); + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_BINOMIAL_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/cauchy_distribution.h b/contrib/llvm-project/libcxx/include/__random/cauchy_distribution.h new file mode 100644 index 000000000000..6661e00bf939 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/cauchy_distribution.h @@ -0,0 +1,162 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_CAUCHY_DISTRIBUTION_H +#define _LIBCPP___RANDOM_CAUCHY_DISTRIBUTION_H + +#include <__config> +#include <__random/uniform_real_distribution.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS cauchy_distribution +{ +public: + // types + typedef _RealType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + result_type __a_; + result_type __b_; + public: + typedef cauchy_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(result_type __a = 0, result_type __b = 1) + : __a_(__a), __b_(__b) {} + + _LIBCPP_INLINE_VISIBILITY + result_type a() const {return __a_;} + _LIBCPP_INLINE_VISIBILITY + result_type b() const {return __b_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + +public: + // constructor and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + cauchy_distribution() : cauchy_distribution(0) {} + _LIBCPP_INLINE_VISIBILITY + explicit cauchy_distribution(result_type __a, result_type __b = 1) + : __p_(param_type(__a, __b)) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit cauchy_distribution(result_type __a = 0, result_type __b = 1) + : __p_(param_type(__a, __b)) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit cauchy_distribution(const param_type& __p) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template _LIBCPP_INLINE_VISIBILITY result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + _LIBCPP_INLINE_VISIBILITY + result_type a() const {return __p_.a();} + _LIBCPP_INLINE_VISIBILITY + result_type b() const {return __p_.b();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return -numeric_limits::infinity();} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return numeric_limits::infinity();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const cauchy_distribution& __x, + const cauchy_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const cauchy_distribution& __x, + const cauchy_distribution& __y) + {return !(__x == __y);} +}; + +template +template +inline +_RealType +cauchy_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) +{ + uniform_real_distribution __gen; + // purposefully let tan arg get as close to pi/2 as it wants, tan will return a finite + return __p.a() + __p.b() * _VSTD::tan(3.1415926535897932384626433832795 * __gen(__g)); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const cauchy_distribution<_RT>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + __os << __x.a() << __sp << __x.b(); + return __os; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + cauchy_distribution<_RT>& __x) +{ + typedef cauchy_distribution<_RT> _Eng; + typedef typename _Eng::result_type result_type; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + result_type __a; + result_type __b; + __is >> __a >> __b; + if (!__is.fail()) + __x.param(param_type(__a, __b)); + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_CAUCHY_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/chi_squared_distribution.h b/contrib/llvm-project/libcxx/include/__random/chi_squared_distribution.h new file mode 100644 index 000000000000..9cf38971bdde --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/chi_squared_distribution.h @@ -0,0 +1,144 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_CHI_SQUARED_DISTRIBUTION_H +#define _LIBCPP___RANDOM_CHI_SQUARED_DISTRIBUTION_H + +#include <__config> +#include <__random/gamma_distribution.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS chi_squared_distribution +{ +public: + // types + typedef _RealType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + result_type __n_; + public: + typedef chi_squared_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(result_type __n = 1) : __n_(__n) {} + + _LIBCPP_INLINE_VISIBILITY + result_type n() const {return __n_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__n_ == __y.__n_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + +public: + // constructor and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + chi_squared_distribution() : chi_squared_distribution(1) {} + _LIBCPP_INLINE_VISIBILITY + explicit chi_squared_distribution(result_type __n) + : __p_(param_type(__n)) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit chi_squared_distribution(result_type __n = 1) + : __p_(param_type(__n)) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit chi_squared_distribution(const param_type& __p) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g, const param_type& __p) + {return gamma_distribution(__p.n() / 2, 2)(__g);} + + // property functions + _LIBCPP_INLINE_VISIBILITY + result_type n() const {return __p_.n();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return 0;} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return numeric_limits::infinity();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const chi_squared_distribution& __x, + const chi_squared_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const chi_squared_distribution& __x, + const chi_squared_distribution& __y) + {return !(__x == __y);} +}; + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const chi_squared_distribution<_RT>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + __os << __x.n(); + return __os; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + chi_squared_distribution<_RT>& __x) +{ + typedef chi_squared_distribution<_RT> _Eng; + typedef typename _Eng::result_type result_type; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + result_type __n; + __is >> __n; + if (!__is.fail()) + __x.param(param_type(__n)); + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_CHI_SQUARED_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/default_random_engine.h b/contrib/llvm-project/libcxx/include/__random/default_random_engine.h new file mode 100644 index 000000000000..61c5cf9c7142 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/default_random_engine.h @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_DEFAULT_RANDOM_ENGINE_H +#define _LIBCPP___RANDOM_DEFAULT_RANDOM_ENGINE_H + +#include <__config> +#include <__random/linear_congruential_engine.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +typedef minstd_rand default_random_engine; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___RANDOM_DEFAULT_RANDOM_ENGINE_H diff --git a/contrib/llvm-project/libcxx/include/__random/discard_block_engine.h b/contrib/llvm-project/libcxx/include/__random/discard_block_engine.h new file mode 100644 index 000000000000..335715211884 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/discard_block_engine.h @@ -0,0 +1,203 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_DISCARD_BLOCK_ENGINE_H +#define _LIBCPP___RANDOM_DISCARD_BLOCK_ENGINE_H + +#include <__config> +#include <__random/is_seed_sequence.h> +#include <__utility/move.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS discard_block_engine +{ + _Engine __e_; + int __n_; + + static_assert( 0 < __r, "discard_block_engine invalid parameters"); + static_assert(__r <= __p, "discard_block_engine invalid parameters"); + static_assert(__r <= INT_MAX, "discard_block_engine invalid parameters"); +public: + // types + typedef typename _Engine::result_type result_type; + + // engine characteristics + static _LIBCPP_CONSTEXPR const size_t block_size = __p; + static _LIBCPP_CONSTEXPR const size_t used_block = __r; + +#ifdef _LIBCPP_CXX03_LANG + static const result_type _Min = _Engine::_Min; + static const result_type _Max = _Engine::_Max; +#else + static _LIBCPP_CONSTEXPR const result_type _Min = _Engine::min(); + static _LIBCPP_CONSTEXPR const result_type _Max = _Engine::max(); +#endif + + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR result_type min() { return _Engine::min(); } + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR result_type max() { return _Engine::max(); } + + // constructors and seeding functions + _LIBCPP_INLINE_VISIBILITY + discard_block_engine() : __n_(0) {} + _LIBCPP_INLINE_VISIBILITY + explicit discard_block_engine(const _Engine& __e) + : __e_(__e), __n_(0) {} +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + explicit discard_block_engine(_Engine&& __e) + : __e_(_VSTD::move(__e)), __n_(0) {} +#endif // _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + explicit discard_block_engine(result_type __sd) : __e_(__sd), __n_(0) {} + template + _LIBCPP_INLINE_VISIBILITY + explicit discard_block_engine(_Sseq& __q, + typename enable_if<__is_seed_sequence<_Sseq, discard_block_engine>::value && + !is_convertible<_Sseq, _Engine>::value>::type* = 0) + : __e_(__q), __n_(0) {} + _LIBCPP_INLINE_VISIBILITY + void seed() {__e_.seed(); __n_ = 0;} + _LIBCPP_INLINE_VISIBILITY + void seed(result_type __sd) {__e_.seed(__sd); __n_ = 0;} + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + __is_seed_sequence<_Sseq, discard_block_engine>::value, + void + >::type + seed(_Sseq& __q) {__e_.seed(__q); __n_ = 0;} + + // generating functions + result_type operator()(); + _LIBCPP_INLINE_VISIBILITY + void discard(unsigned long long __z) {for (; __z; --__z) operator()();} + + // property functions + _LIBCPP_INLINE_VISIBILITY + const _Engine& base() const _NOEXCEPT {return __e_;} + + template + friend + bool + operator==( + const discard_block_engine<_Eng, _Pp, _Rp>& __x, + const discard_block_engine<_Eng, _Pp, _Rp>& __y); + + template + friend + bool + operator!=( + const discard_block_engine<_Eng, _Pp, _Rp>& __x, + const discard_block_engine<_Eng, _Pp, _Rp>& __y); + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const discard_block_engine<_Eng, _Pp, _Rp>& __x); + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + discard_block_engine<_Eng, _Pp, _Rp>& __x); +}; + +template + _LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::block_size; + +template + _LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::used_block; + +template +typename discard_block_engine<_Engine, __p, __r>::result_type +discard_block_engine<_Engine, __p, __r>::operator()() +{ + if (__n_ >= static_cast(__r)) + { + __e_.discard(__p - __r); + __n_ = 0; + } + ++__n_; + return __e_(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const discard_block_engine<_Eng, _Pp, _Rp>& __x, + const discard_block_engine<_Eng, _Pp, _Rp>& __y) +{ + return __x.__n_ == __y.__n_ && __x.__e_ == __y.__e_; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const discard_block_engine<_Eng, _Pp, _Rp>& __x, + const discard_block_engine<_Eng, _Pp, _Rp>& __y) +{ + return !(__x == __y); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const discard_block_engine<_Eng, _Pp, _Rp>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _Ostream; + __os.flags(_Ostream::dec | _Ostream::left); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + return __os << __x.__e_ << __sp << __x.__n_; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + discard_block_engine<_Eng, _Pp, _Rp>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + _Eng __e; + int __n; + __is >> __e >> __n; + if (!__is.fail()) + { + __x.__e_ = __e; + __x.__n_ = __n; + } + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_DISCARD_BLOCK_ENGINE_H diff --git a/contrib/llvm-project/libcxx/include/__random/discrete_distribution.h b/contrib/llvm-project/libcxx/include/__random/discrete_distribution.h new file mode 100644 index 000000000000..dc9881a92c38 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/discrete_distribution.h @@ -0,0 +1,260 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_DISCRETE_DISTRIBUTION_H +#define _LIBCPP___RANDOM_DISCRETE_DISTRIBUTION_H + +#include <__algorithm/upper_bound.h> +#include <__config> +#include <__random/uniform_real_distribution.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS discrete_distribution +{ +public: + // types + typedef _IntType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + vector __p_; + public: + typedef discrete_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + param_type() {} + template + _LIBCPP_INLINE_VISIBILITY + param_type(_InputIterator __f, _InputIterator __l) + : __p_(__f, __l) {__init();} +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + param_type(initializer_list __wl) + : __p_(__wl.begin(), __wl.end()) {__init();} +#endif // _LIBCPP_CXX03_LANG + template + param_type(size_t __nw, double __xmin, double __xmax, + _UnaryOperation __fw); + + vector probabilities() const; + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + + private: + void __init(); + + friend class discrete_distribution; + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const discrete_distribution<_IT>& __x); + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + discrete_distribution<_IT>& __x); + }; + +private: + param_type __p_; + +public: + // constructor and reset functions + _LIBCPP_INLINE_VISIBILITY + discrete_distribution() {} + template + _LIBCPP_INLINE_VISIBILITY + discrete_distribution(_InputIterator __f, _InputIterator __l) + : __p_(__f, __l) {} +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + discrete_distribution(initializer_list __wl) + : __p_(__wl) {} +#endif // _LIBCPP_CXX03_LANG + template + _LIBCPP_INLINE_VISIBILITY + discrete_distribution(size_t __nw, double __xmin, double __xmax, + _UnaryOperation __fw) + : __p_(__nw, __xmin, __xmax, __fw) {} + _LIBCPP_INLINE_VISIBILITY + explicit discrete_distribution(const param_type& __p) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + _LIBCPP_INLINE_VISIBILITY + vector probabilities() const {return __p_.probabilities();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return 0;} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return __p_.__p_.size();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const discrete_distribution& __x, + const discrete_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const discrete_distribution& __x, + const discrete_distribution& __y) + {return !(__x == __y);} + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const discrete_distribution<_IT>& __x); + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + discrete_distribution<_IT>& __x); +}; + +template +template +discrete_distribution<_IntType>::param_type::param_type(size_t __nw, + double __xmin, + double __xmax, + _UnaryOperation __fw) +{ + if (__nw > 1) + { + __p_.reserve(__nw - 1); + double __d = (__xmax - __xmin) / __nw; + double __d2 = __d / 2; + for (size_t __k = 0; __k < __nw; ++__k) + __p_.push_back(__fw(__xmin + __k * __d + __d2)); + __init(); + } +} + +template +void +discrete_distribution<_IntType>::param_type::__init() +{ + if (!__p_.empty()) + { + if (__p_.size() > 1) + { + double __s = _VSTD::accumulate(__p_.begin(), __p_.end(), 0.0); + for (vector::iterator __i = __p_.begin(), __e = __p_.end(); __i < __e; ++__i) + *__i /= __s; + vector __t(__p_.size() - 1); + _VSTD::partial_sum(__p_.begin(), __p_.end() - 1, __t.begin()); + swap(__p_, __t); + } + else + { + __p_.clear(); + __p_.shrink_to_fit(); + } + } +} + +template +vector +discrete_distribution<_IntType>::param_type::probabilities() const +{ + size_t __n = __p_.size(); + vector __p(__n+1); + _VSTD::adjacent_difference(__p_.begin(), __p_.end(), __p.begin()); + if (__n > 0) + __p[__n] = 1 - __p_[__n-1]; + else + __p[0] = 1; + return __p; +} + +template +template +_IntType +discrete_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p) +{ + uniform_real_distribution __gen; + return static_cast<_IntType>( + _VSTD::upper_bound(__p.__p_.begin(), __p.__p_.end(), __gen(__g)) - + __p.__p_.begin()); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const discrete_distribution<_IT>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + size_t __n = __x.__p_.__p_.size(); + __os << __n; + for (size_t __i = 0; __i < __n; ++__i) + __os << __sp << __x.__p_.__p_[__i]; + return __os; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + discrete_distribution<_IT>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + size_t __n; + __is >> __n; + vector __p(__n); + for (size_t __i = 0; __i < __n; ++__i) + __is >> __p[__i]; + if (!__is.fail()) + swap(__x.__p_.__p_, __p); + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_DISCRETE_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/exponential_distribution.h b/contrib/llvm-project/libcxx/include/__random/exponential_distribution.h new file mode 100644 index 000000000000..9e555f0c1075 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/exponential_distribution.h @@ -0,0 +1,155 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_EXPONENTIAL_DISTRIBUTION_H +#define _LIBCPP___RANDOM_EXPONENTIAL_DISTRIBUTION_H + +#include <__config> +#include <__random/generate_canonical.h> +#include <__random/uniform_real_distribution.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS exponential_distribution +{ +public: + // types + typedef _RealType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + result_type __lambda_; + public: + typedef exponential_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(result_type __lambda = 1) : __lambda_(__lambda) {} + + _LIBCPP_INLINE_VISIBILITY + result_type lambda() const {return __lambda_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__lambda_ == __y.__lambda_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + +public: + // constructors and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + exponential_distribution() : exponential_distribution(1) {} + _LIBCPP_INLINE_VISIBILITY + explicit exponential_distribution(result_type __lambda) + : __p_(param_type(__lambda)) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit exponential_distribution(result_type __lambda = 1) + : __p_(param_type(__lambda)) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit exponential_distribution(const param_type& __p) : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + _LIBCPP_INLINE_VISIBILITY + result_type lambda() const {return __p_.lambda();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return 0;} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return numeric_limits::infinity();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const exponential_distribution& __x, + const exponential_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const exponential_distribution& __x, + const exponential_distribution& __y) + {return !(__x == __y);} +}; + +template +template +_RealType +exponential_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) +{ + return -_VSTD::log + ( + result_type(1) - + _VSTD::generate_canonical::digits>(__g) + ) + / __p.lambda(); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const exponential_distribution<_RealType>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + return __os << __x.lambda(); +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + exponential_distribution<_RealType>& __x) +{ + typedef exponential_distribution<_RealType> _Eng; + typedef typename _Eng::result_type result_type; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + result_type __lambda; + __is >> __lambda; + if (!__is.fail()) + __x.param(param_type(__lambda)); + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_EXPONENTIAL_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/extreme_value_distribution.h b/contrib/llvm-project/libcxx/include/__random/extreme_value_distribution.h new file mode 100644 index 000000000000..0e200f91d7ff --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/extreme_value_distribution.h @@ -0,0 +1,161 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_EXTREME_VALUE_DISTRIBUTION_H +#define _LIBCPP___RANDOM_EXTREME_VALUE_DISTRIBUTION_H + +#include <__config> +#include <__random/uniform_real_distribution.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS extreme_value_distribution +{ +public: + // types + typedef _RealType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + result_type __a_; + result_type __b_; + public: + typedef extreme_value_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(result_type __a = 0, result_type __b = 1) + : __a_(__a), __b_(__b) {} + + _LIBCPP_INLINE_VISIBILITY + result_type a() const {return __a_;} + _LIBCPP_INLINE_VISIBILITY + result_type b() const {return __b_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + +public: + // constructor and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + extreme_value_distribution() : extreme_value_distribution(0) {} + _LIBCPP_INLINE_VISIBILITY + explicit extreme_value_distribution(result_type __a, result_type __b = 1) + : __p_(param_type(__a, __b)) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit extreme_value_distribution(result_type __a = 0, + result_type __b = 1) + : __p_(param_type(__a, __b)) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit extreme_value_distribution(const param_type& __p) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + _LIBCPP_INLINE_VISIBILITY + result_type a() const {return __p_.a();} + _LIBCPP_INLINE_VISIBILITY + result_type b() const {return __p_.b();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return -numeric_limits::infinity();} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return numeric_limits::infinity();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const extreme_value_distribution& __x, + const extreme_value_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const extreme_value_distribution& __x, + const extreme_value_distribution& __y) + {return !(__x == __y);} +}; + +template +template +_RealType +extreme_value_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) +{ + return __p.a() - __p.b() * + _VSTD::log(-_VSTD::log(1-uniform_real_distribution()(__g))); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const extreme_value_distribution<_RT>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + __os << __x.a() << __sp << __x.b(); + return __os; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + extreme_value_distribution<_RT>& __x) +{ + typedef extreme_value_distribution<_RT> _Eng; + typedef typename _Eng::result_type result_type; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + result_type __a; + result_type __b; + __is >> __a >> __b; + if (!__is.fail()) + __x.param(param_type(__a, __b)); + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_EXTREME_VALUE_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/fisher_f_distribution.h b/contrib/llvm-project/libcxx/include/__random/fisher_f_distribution.h new file mode 100644 index 000000000000..bf64d33a645a --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/fisher_f_distribution.h @@ -0,0 +1,160 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_FISHER_F_DISTRIBUTION_H +#define _LIBCPP___RANDOM_FISHER_F_DISTRIBUTION_H + +#include <__config> +#include <__random/gamma_distribution.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS fisher_f_distribution +{ +public: + // types + typedef _RealType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + result_type __m_; + result_type __n_; + public: + typedef fisher_f_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(result_type __m = 1, result_type __n = 1) + : __m_(__m), __n_(__n) {} + + _LIBCPP_INLINE_VISIBILITY + result_type m() const {return __m_;} + _LIBCPP_INLINE_VISIBILITY + result_type n() const {return __n_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__m_ == __y.__m_ && __x.__n_ == __y.__n_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + +public: + // constructor and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + fisher_f_distribution() : fisher_f_distribution(1) {} + _LIBCPP_INLINE_VISIBILITY + explicit fisher_f_distribution(result_type __m, result_type __n = 1) + : __p_(param_type(__m, __n)) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit fisher_f_distribution(result_type __m = 1, result_type __n = 1) + : __p_(param_type(__m, __n)) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit fisher_f_distribution(const param_type& __p) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + _LIBCPP_INLINE_VISIBILITY + result_type m() const {return __p_.m();} + _LIBCPP_INLINE_VISIBILITY + result_type n() const {return __p_.n();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return 0;} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return numeric_limits::infinity();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const fisher_f_distribution& __x, + const fisher_f_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const fisher_f_distribution& __x, + const fisher_f_distribution& __y) + {return !(__x == __y);} +}; + +template +template +_RealType +fisher_f_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) +{ + gamma_distribution __gdm(__p.m() * result_type(.5)); + gamma_distribution __gdn(__p.n() * result_type(.5)); + return __p.n() * __gdm(__g) / (__p.m() * __gdn(__g)); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const fisher_f_distribution<_RT>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + __os << __x.m() << __sp << __x.n(); + return __os; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + fisher_f_distribution<_RT>& __x) +{ + typedef fisher_f_distribution<_RT> _Eng; + typedef typename _Eng::result_type result_type; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + result_type __m; + result_type __n; + __is >> __m >> __n; + if (!__is.fail()) + __x.param(param_type(__m, __n)); + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_FISHER_F_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/gamma_distribution.h b/contrib/llvm-project/libcxx/include/__random/gamma_distribution.h new file mode 100644 index 000000000000..49d024eafea2 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/gamma_distribution.h @@ -0,0 +1,213 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_GAMMA_DISTRIBUTION_H +#define _LIBCPP___RANDOM_GAMMA_DISTRIBUTION_H + +#include <__config> +#include <__random/uniform_real_distribution.h> +#include <__random/exponential_distribution.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS gamma_distribution +{ +public: + // types + typedef _RealType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + result_type __alpha_; + result_type __beta_; + public: + typedef gamma_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(result_type __alpha = 1, result_type __beta = 1) + : __alpha_(__alpha), __beta_(__beta) {} + + _LIBCPP_INLINE_VISIBILITY + result_type alpha() const {return __alpha_;} + _LIBCPP_INLINE_VISIBILITY + result_type beta() const {return __beta_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__alpha_ == __y.__alpha_ && __x.__beta_ == __y.__beta_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + +public: + // constructors and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + gamma_distribution() : gamma_distribution(1) {} + _LIBCPP_INLINE_VISIBILITY + explicit gamma_distribution(result_type __alpha, result_type __beta = 1) + : __p_(param_type(__alpha, __beta)) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit gamma_distribution(result_type __alpha = 1, + result_type __beta = 1) + : __p_(param_type(__alpha, __beta)) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit gamma_distribution(const param_type& __p) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + _LIBCPP_INLINE_VISIBILITY + result_type alpha() const {return __p_.alpha();} + _LIBCPP_INLINE_VISIBILITY + result_type beta() const {return __p_.beta();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return 0;} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return numeric_limits::infinity();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const gamma_distribution& __x, + const gamma_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const gamma_distribution& __x, + const gamma_distribution& __y) + {return !(__x == __y);} +}; + +template +template +_RealType +gamma_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) +{ + result_type __a = __p.alpha(); + uniform_real_distribution __gen(0, 1); + exponential_distribution __egen; + result_type __x; + if (__a == 1) + __x = __egen(__g); + else if (__a > 1) + { + const result_type __b = __a - 1; + const result_type __c = 3 * __a - result_type(0.75); + while (true) + { + const result_type __u = __gen(__g); + const result_type __v = __gen(__g); + const result_type __w = __u * (1 - __u); + if (__w != 0) + { + const result_type __y = _VSTD::sqrt(__c / __w) * + (__u - result_type(0.5)); + __x = __b + __y; + if (__x >= 0) + { + const result_type __z = 64 * __w * __w * __w * __v * __v; + if (__z <= 1 - 2 * __y * __y / __x) + break; + if (_VSTD::log(__z) <= 2 * (__b * _VSTD::log(__x / __b) - __y)) + break; + } + } + } + } + else // __a < 1 + { + while (true) + { + const result_type __u = __gen(__g); + const result_type __es = __egen(__g); + if (__u <= 1 - __a) + { + __x = _VSTD::pow(__u, 1 / __a); + if (__x <= __es) + break; + } + else + { + const result_type __e = -_VSTD::log((1-__u)/__a); + __x = _VSTD::pow(1 - __a + __a * __e, 1 / __a); + if (__x <= __e + __es) + break; + } + } + } + return __x * __p.beta(); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const gamma_distribution<_RT>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + __os << __x.alpha() << __sp << __x.beta(); + return __os; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + gamma_distribution<_RT>& __x) +{ + typedef gamma_distribution<_RT> _Eng; + typedef typename _Eng::result_type result_type; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + result_type __alpha; + result_type __beta; + __is >> __alpha >> __beta; + if (!__is.fail()) + __x.param(param_type(__alpha, __beta)); + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_GAMMA_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/generate_canonical.h b/contrib/llvm-project/libcxx/include/__random/generate_canonical.h new file mode 100644 index 000000000000..46c3b2980952 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/generate_canonical.h @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___RANDOM_GENERATE_CANONICAL_H +#define _LIBCPP___RANDOM_GENERATE_CANONICAL_H + +#include <__config> +#include <__random/log2.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// generate_canonical + +template +_RealType +generate_canonical(_URNG& __g) +{ + const size_t _Dt = numeric_limits<_RealType>::digits; + const size_t __b = _Dt < __bits ? _Dt : __bits; +#ifdef _LIBCPP_CXX03_LANG + const size_t __logR = __log2::value; +#else + const size_t __logR = __log2::value; +#endif + const size_t __k = __b / __logR + (__b % __logR != 0) + (__b == 0); + const _RealType _Rp = static_cast<_RealType>(_URNG::max() - _URNG::min()) + _RealType(1); + _RealType __base = _Rp; + _RealType _Sp = __g() - _URNG::min(); + for (size_t __i = 1; __i < __k; ++__i, __base *= _Rp) + _Sp += (__g() - _URNG::min()) * __base; + return _Sp / __base; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_GENERATE_CANONICAL_H diff --git a/contrib/llvm-project/libcxx/include/__random/geometric_distribution.h b/contrib/llvm-project/libcxx/include/__random/geometric_distribution.h new file mode 100644 index 000000000000..174914eaed2e --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/geometric_distribution.h @@ -0,0 +1,141 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_GEOMETRIC_DISTRIBUTION_H +#define _LIBCPP___RANDOM_GEOMETRIC_DISTRIBUTION_H + +#include <__config> +#include <__random/negative_binomial_distribution.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS geometric_distribution +{ +public: + // types + typedef _IntType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + double __p_; + public: + typedef geometric_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(double __p = 0.5) : __p_(__p) {} + + _LIBCPP_INLINE_VISIBILITY + double p() const {return __p_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + +public: + // constructors and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + geometric_distribution() : geometric_distribution(0.5) {} + _LIBCPP_INLINE_VISIBILITY + explicit geometric_distribution(double __p) + : __p_(__p) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit geometric_distribution(double __p = 0.5) + : __p_(__p) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit geometric_distribution(const param_type& __p) : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g, const param_type& __p) + {return negative_binomial_distribution(1, __p.p())(__g);} + + // property functions + _LIBCPP_INLINE_VISIBILITY + double p() const {return __p_.p();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return 0;} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return numeric_limits::max();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const geometric_distribution& __x, + const geometric_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const geometric_distribution& __x, + const geometric_distribution& __y) + {return !(__x == __y);} +}; + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const geometric_distribution<_IntType>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + return __os << __x.p(); +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + geometric_distribution<_IntType>& __x) +{ + typedef geometric_distribution<_IntType> _Eng; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + double __p; + __is >> __p; + if (!__is.fail()) + __x.param(param_type(__p)); + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_GEOMETRIC_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/independent_bits_engine.h b/contrib/llvm-project/libcxx/include/__random/independent_bits_engine.h new file mode 100644 index 000000000000..f0e8c654246b --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/independent_bits_engine.h @@ -0,0 +1,271 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_INDEPENDENT_BITS_ENGINE_H +#define _LIBCPP___RANDOM_INDEPENDENT_BITS_ENGINE_H + +#include <__config> +#include <__random/is_seed_sequence.h> +#include <__random/log2.h> +#include <__utility/move.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS independent_bits_engine +{ + template + class __get_n + { + static _LIBCPP_CONSTEXPR const size_t _Dt = numeric_limits<_UInt>::digits; + static _LIBCPP_CONSTEXPR const size_t _Np = _Wp / _Mp + (_Wp % _Mp != 0); + static _LIBCPP_CONSTEXPR const size_t _W0 = _Wp / _Np; + static _LIBCPP_CONSTEXPR const _UInt _Y0 = _W0 >= _Dt ? 0 : (_R0 >> _W0) << _W0; + public: + static _LIBCPP_CONSTEXPR const size_t value = _R0 - _Y0 > _Y0 / _Np ? _Np + 1 : _Np; + }; +public: + // types + typedef _UIntType result_type; + +private: + _Engine __e_; + + static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits::digits; + static_assert( 0 < __w, "independent_bits_engine invalid parameters"); + static_assert(__w <= _Dt, "independent_bits_engine invalid parameters"); + + typedef typename _Engine::result_type _Engine_result_type; + typedef typename conditional + < + sizeof(_Engine_result_type) <= sizeof(result_type), + result_type, + _Engine_result_type + >::type _Working_result_type; +#ifdef _LIBCPP_CXX03_LANG + static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min + + _Working_result_type(1); +#else + static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min() + + _Working_result_type(1); +#endif + static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value; + static _LIBCPP_CONSTEXPR const size_t __n = __get_n<_Working_result_type, _Rp, __w, __m>::value; + static _LIBCPP_CONSTEXPR const size_t __w0 = __w / __n; + static _LIBCPP_CONSTEXPR const size_t __n0 = __n - __w % __n; + static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits; + static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits; + static _LIBCPP_CONSTEXPR const _Working_result_type __y0 = __w0 >= _WDt ? 0 : + (_Rp >> __w0) << __w0; + static _LIBCPP_CONSTEXPR const _Working_result_type __y1 = __w0 >= _WDt - 1 ? 0 : + (_Rp >> (__w0+1)) << (__w0+1); + static _LIBCPP_CONSTEXPR const _Engine_result_type __mask0 = __w0 > 0 ? + _Engine_result_type(~0) >> (_EDt - __w0) : + _Engine_result_type(0); + static _LIBCPP_CONSTEXPR const _Engine_result_type __mask1 = __w0 < _EDt - 1 ? + _Engine_result_type(~0) >> (_EDt - (__w0 + 1)) : + _Engine_result_type(~0); +public: + static _LIBCPP_CONSTEXPR const result_type _Min = 0; + static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) : + (result_type(1) << __w) - result_type(1); + static_assert(_Min < _Max, "independent_bits_engine invalid parameters"); + + // engine characteristics + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR result_type min() { return _Min; } + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR result_type max() { return _Max; } + + // constructors and seeding functions + _LIBCPP_INLINE_VISIBILITY + independent_bits_engine() {} + _LIBCPP_INLINE_VISIBILITY + explicit independent_bits_engine(const _Engine& __e) + : __e_(__e) {} +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + explicit independent_bits_engine(_Engine&& __e) + : __e_(_VSTD::move(__e)) {} +#endif // _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + explicit independent_bits_engine(result_type __sd) : __e_(__sd) {} + template + _LIBCPP_INLINE_VISIBILITY + explicit independent_bits_engine(_Sseq& __q, + typename enable_if<__is_seed_sequence<_Sseq, independent_bits_engine>::value && + !is_convertible<_Sseq, _Engine>::value>::type* = 0) + : __e_(__q) {} + _LIBCPP_INLINE_VISIBILITY + void seed() {__e_.seed();} + _LIBCPP_INLINE_VISIBILITY + void seed(result_type __sd) {__e_.seed(__sd);} + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + __is_seed_sequence<_Sseq, independent_bits_engine>::value, + void + >::type + seed(_Sseq& __q) {__e_.seed(__q);} + + // generating functions + _LIBCPP_INLINE_VISIBILITY + result_type operator()() {return __eval(integral_constant());} + _LIBCPP_INLINE_VISIBILITY + void discard(unsigned long long __z) {for (; __z; --__z) operator()();} + + // property functions + _LIBCPP_INLINE_VISIBILITY + const _Engine& base() const _NOEXCEPT {return __e_;} + + template + friend + bool + operator==( + const independent_bits_engine<_Eng, _Wp, _UInt>& __x, + const independent_bits_engine<_Eng, _Wp, _UInt>& __y); + + template + friend + bool + operator!=( + const independent_bits_engine<_Eng, _Wp, _UInt>& __x, + const independent_bits_engine<_Eng, _Wp, _UInt>& __y); + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const independent_bits_engine<_Eng, _Wp, _UInt>& __x); + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + independent_bits_engine<_Eng, _Wp, _UInt>& __x); + +private: + _LIBCPP_INLINE_VISIBILITY + result_type __eval(false_type); + result_type __eval(true_type); + + template + _LIBCPP_INLINE_VISIBILITY + static + typename enable_if + < + __count < _Dt, + result_type + >::type + __lshift(result_type __x) {return __x << __count;} + + template + _LIBCPP_INLINE_VISIBILITY + static + typename enable_if + < + (__count >= _Dt), + result_type + >::type + __lshift(result_type) {return result_type(0);} +}; + +template +inline +_UIntType +independent_bits_engine<_Engine, __w, _UIntType>::__eval(false_type) +{ + return static_cast(__e_() & __mask0); +} + +template +_UIntType +independent_bits_engine<_Engine, __w, _UIntType>::__eval(true_type) +{ + result_type _Sp = 0; + for (size_t __k = 0; __k < __n0; ++__k) + { + _Engine_result_type __u; + do + { + __u = __e_() - _Engine::min(); + } while (__u >= __y0); + _Sp = static_cast(__lshift<__w0>(_Sp) + (__u & __mask0)); + } + for (size_t __k = __n0; __k < __n; ++__k) + { + _Engine_result_type __u; + do + { + __u = __e_() - _Engine::min(); + } while (__u >= __y1); + _Sp = static_cast(__lshift<__w0+1>(_Sp) + (__u & __mask1)); + } + return _Sp; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==( + const independent_bits_engine<_Eng, _Wp, _UInt>& __x, + const independent_bits_engine<_Eng, _Wp, _UInt>& __y) +{ + return __x.base() == __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=( + const independent_bits_engine<_Eng, _Wp, _UInt>& __x, + const independent_bits_engine<_Eng, _Wp, _UInt>& __y) +{ + return !(__x == __y); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const independent_bits_engine<_Eng, _Wp, _UInt>& __x) +{ + return __os << __x.base(); +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + independent_bits_engine<_Eng, _Wp, _UInt>& __x) +{ + _Eng __e; + __is >> __e; + if (!__is.fail()) + __x.__e_ = __e; + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_INDEPENDENT_BITS_ENGINE_H diff --git a/contrib/llvm-project/libcxx/include/__random/is_seed_sequence.h b/contrib/llvm-project/libcxx/include/__random/is_seed_sequence.h new file mode 100644 index 000000000000..46b1d719ddfb --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/is_seed_sequence.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___RANDOM_IS_SEED_SEQUENCE_H +#define _LIBCPP___RANDOM_IS_SEED_SEQUENCE_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __is_seed_sequence +{ + static _LIBCPP_CONSTEXPR const bool value = + !is_convertible<_Sseq, typename _Engine::result_type>::value && + !is_same::type, _Engine>::value; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___RANDOM_IS_SEED_SEQUENCE_H diff --git a/contrib/llvm-project/libcxx/include/__random/knuth_b.h b/contrib/llvm-project/libcxx/include/__random/knuth_b.h new file mode 100644 index 000000000000..ade853884dd3 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/knuth_b.h @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_KNUTH_B_H +#define _LIBCPP___RANDOM_KNUTH_B_H + +#include <__config> +#include <__random/linear_congruential_engine.h> +#include <__random/shuffle_order_engine.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +typedef shuffle_order_engine knuth_b; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___RANDOM_KNUTH_B_H diff --git a/contrib/llvm-project/libcxx/include/__random/linear_congruential_engine.h b/contrib/llvm-project/libcxx/include/__random/linear_congruential_engine.h new file mode 100644 index 000000000000..64c9f584114c --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/linear_congruential_engine.h @@ -0,0 +1,398 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H +#define _LIBCPP___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H + +#include <__config> +#include <__random/is_seed_sequence.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template (_Mp-__c)/__a), + bool _OverflowOK = ((__m | (__m-1)) > __m), // m = 2^n + bool _SchrageOK = (__a != 0 && __m != 0 && __m % __a <= __m / __a)> // r <= q +struct __lce_alg_picker +{ + static_assert(__a != 0 || __m != 0 || !_MightOverflow || _OverflowOK || _SchrageOK, + "The current values of a, c, and m cannot generate a number " + "within bounds of linear_congruential_engine."); + + static _LIBCPP_CONSTEXPR const bool __use_schrage = _MightOverflow && + !_OverflowOK && + _SchrageOK; +}; + +template ::__use_schrage> +struct __lce_ta; + +// 64 + +template +struct __lce_ta<__a, __c, __m, (unsigned long long)(~0), true> +{ + typedef unsigned long long result_type; + _LIBCPP_INLINE_VISIBILITY + static result_type next(result_type __x) + { + // Schrage's algorithm + const result_type __q = __m / __a; + const result_type __r = __m % __a; + const result_type __t0 = __a * (__x % __q); + const result_type __t1 = __r * (__x / __q); + __x = __t0 + (__t0 < __t1) * __m - __t1; + __x += __c - (__x >= __m - __c) * __m; + return __x; + } +}; + +template +struct __lce_ta<__a, 0, __m, (unsigned long long)(~0), true> +{ + typedef unsigned long long result_type; + _LIBCPP_INLINE_VISIBILITY + static result_type next(result_type __x) + { + // Schrage's algorithm + const result_type __q = __m / __a; + const result_type __r = __m % __a; + const result_type __t0 = __a * (__x % __q); + const result_type __t1 = __r * (__x / __q); + __x = __t0 + (__t0 < __t1) * __m - __t1; + return __x; + } +}; + +template +struct __lce_ta<__a, __c, __m, (unsigned long long)(~0), false> +{ + typedef unsigned long long result_type; + _LIBCPP_INLINE_VISIBILITY + static result_type next(result_type __x) + { + return (__a * __x + __c) % __m; + } +}; + +template +struct __lce_ta<__a, __c, 0, (unsigned long long)(~0), false> +{ + typedef unsigned long long result_type; + _LIBCPP_INLINE_VISIBILITY + static result_type next(result_type __x) + { + return __a * __x + __c; + } +}; + +// 32 + +template +struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), true> +{ + typedef unsigned result_type; + _LIBCPP_INLINE_VISIBILITY + static result_type next(result_type __x) + { + const result_type __a = static_cast(_Ap); + const result_type __c = static_cast(_Cp); + const result_type __m = static_cast(_Mp); + // Schrage's algorithm + const result_type __q = __m / __a; + const result_type __r = __m % __a; + const result_type __t0 = __a * (__x % __q); + const result_type __t1 = __r * (__x / __q); + __x = __t0 + (__t0 < __t1) * __m - __t1; + __x += __c - (__x >= __m - __c) * __m; + return __x; + } +}; + +template +struct __lce_ta<_Ap, 0, _Mp, unsigned(~0), true> +{ + typedef unsigned result_type; + _LIBCPP_INLINE_VISIBILITY + static result_type next(result_type __x) + { + const result_type __a = static_cast(_Ap); + const result_type __m = static_cast(_Mp); + // Schrage's algorithm + const result_type __q = __m / __a; + const result_type __r = __m % __a; + const result_type __t0 = __a * (__x % __q); + const result_type __t1 = __r * (__x / __q); + __x = __t0 + (__t0 < __t1) * __m - __t1; + return __x; + } +}; + +template +struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), false> +{ + typedef unsigned result_type; + _LIBCPP_INLINE_VISIBILITY + static result_type next(result_type __x) + { + const result_type __a = static_cast(_Ap); + const result_type __c = static_cast(_Cp); + const result_type __m = static_cast(_Mp); + return (__a * __x + __c) % __m; + } +}; + +template +struct __lce_ta<_Ap, _Cp, 0, unsigned(~0), false> +{ + typedef unsigned result_type; + _LIBCPP_INLINE_VISIBILITY + static result_type next(result_type __x) + { + const result_type __a = static_cast(_Ap); + const result_type __c = static_cast(_Cp); + return __a * __x + __c; + } +}; + +// 16 + +template +struct __lce_ta<__a, __c, __m, (unsigned short)(~0), __b> +{ + typedef unsigned short result_type; + _LIBCPP_INLINE_VISIBILITY + static result_type next(result_type __x) + { + return static_cast(__lce_ta<__a, __c, __m, unsigned(~0)>::next(__x)); + } +}; + +template +class _LIBCPP_TEMPLATE_VIS linear_congruential_engine; + +template +_LIBCPP_INLINE_VISIBILITY +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&); + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x); + +template +class _LIBCPP_TEMPLATE_VIS linear_congruential_engine +{ +public: + // types + typedef _UIntType result_type; + +private: + result_type __x_; + + static _LIBCPP_CONSTEXPR const result_type _Mp = result_type(~0); + + static_assert(__m == 0 || __a < __m, "linear_congruential_engine invalid parameters"); + static_assert(__m == 0 || __c < __m, "linear_congruential_engine invalid parameters"); + static_assert(is_unsigned<_UIntType>::value, "_UIntType must be unsigned type"); +public: + static _LIBCPP_CONSTEXPR const result_type _Min = __c == 0u ? 1u: 0u; + static _LIBCPP_CONSTEXPR const result_type _Max = __m - 1u; + static_assert(_Min < _Max, "linear_congruential_engine invalid parameters"); + + // engine characteristics + static _LIBCPP_CONSTEXPR const result_type multiplier = __a; + static _LIBCPP_CONSTEXPR const result_type increment = __c; + static _LIBCPP_CONSTEXPR const result_type modulus = __m; + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR result_type min() {return _Min;} + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR result_type max() {return _Max;} + static _LIBCPP_CONSTEXPR const result_type default_seed = 1u; + + // constructors and seeding functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + linear_congruential_engine() : linear_congruential_engine(default_seed) {} + _LIBCPP_INLINE_VISIBILITY + explicit linear_congruential_engine(result_type __s) { seed(__s); } +#else + _LIBCPP_INLINE_VISIBILITY + explicit linear_congruential_engine(result_type __s = default_seed) { + seed(__s); + } +#endif + template + _LIBCPP_INLINE_VISIBILITY + explicit linear_congruential_engine(_Sseq& __q, + typename enable_if<__is_seed_sequence<_Sseq, linear_congruential_engine>::value>::type* = 0) + {seed(__q);} + _LIBCPP_INLINE_VISIBILITY + void seed(result_type __s = default_seed) + {seed(integral_constant(), + integral_constant(), __s);} + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + __is_seed_sequence<_Sseq, linear_congruential_engine>::value, + void + >::type + seed(_Sseq& __q) + {__seed(__q, integral_constant 0x100000000ull))>());} + + // generating functions + _LIBCPP_INLINE_VISIBILITY + result_type operator()() + {return __x_ = static_cast(__lce_ta<__a, __c, __m, _Mp>::next(__x_));} + _LIBCPP_INLINE_VISIBILITY + void discard(unsigned long long __z) {for (; __z; --__z) operator()();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const linear_congruential_engine& __x, + const linear_congruential_engine& __y) + {return __x.__x_ == __y.__x_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const linear_congruential_engine& __x, + const linear_congruential_engine& __y) + {return !(__x == __y);} + +private: + + _LIBCPP_INLINE_VISIBILITY + void seed(true_type, true_type, result_type __s) {__x_ = __s == 0 ? 1 : __s;} + _LIBCPP_INLINE_VISIBILITY + void seed(true_type, false_type, result_type __s) {__x_ = __s;} + _LIBCPP_INLINE_VISIBILITY + void seed(false_type, true_type, result_type __s) {__x_ = __s % __m == 0 ? + 1 : __s % __m;} + _LIBCPP_INLINE_VISIBILITY + void seed(false_type, false_type, result_type __s) {__x_ = __s % __m;} + + template + void __seed(_Sseq& __q, integral_constant); + template + void __seed(_Sseq& __q, integral_constant); + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&); + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x); +}; + +template + _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type + linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier; + +template + _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type + linear_congruential_engine<_UIntType, __a, __c, __m>::increment; + +template + _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type + linear_congruential_engine<_UIntType, __a, __c, __m>::modulus; + +template + _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type + linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed; + +template +template +void +linear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q, + integral_constant) +{ + const unsigned __k = 1; + uint32_t __ar[__k+3]; + __q.generate(__ar, __ar + __k + 3); + result_type __s = static_cast(__ar[3] % __m); + __x_ = __c == 0 && __s == 0 ? result_type(1) : __s; +} + +template +template +void +linear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q, + integral_constant) +{ + const unsigned __k = 2; + uint32_t __ar[__k+3]; + __q.generate(__ar, __ar + __k + 3); + result_type __s = static_cast((__ar[3] + + ((uint64_t)__ar[4] << 32)) % __m); + __x_ = __c == 0 && __s == 0 ? result_type(1) : __s; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const linear_congruential_engine<_UIntType, __a, __c, __m>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _Ostream; + __os.flags(_Ostream::dec | _Ostream::left); + __os.fill(__os.widen(' ')); + return __os << __x.__x_; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + linear_congruential_engine<_UIntType, __a, __c, __m>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + _UIntType __t; + __is >> __t; + if (!__is.fail()) + __x.__x_ = __t; + return __is; +} + +typedef linear_congruential_engine + minstd_rand0; +typedef linear_congruential_engine + minstd_rand; + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H diff --git a/contrib/llvm-project/libcxx/include/__random/log2.h b/contrib/llvm-project/libcxx/include/__random/log2.h new file mode 100644 index 000000000000..3d9640c1f787 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/log2.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___RANDOM_LOG2_H +#define _LIBCPP___RANDOM_LOG2_H + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __log2_imp; + +template +struct __log2_imp +{ + static const size_t value = _Xp & ((unsigned long long)(1) << _Rp) ? _Rp + : __log2_imp::value; +}; + +template +struct __log2_imp +{ + static const size_t value = 0; +}; + +template +struct __log2_imp +{ + static const size_t value = _Rp + 1; +}; + +#ifndef _LIBCPP_HAS_NO_INT128 + +template <__uint128_t _Xp, size_t _Rp> +struct __log2_imp<__uint128_t, _Xp, _Rp> +{ + static const size_t value = (_Xp >> 64) + ? (64 + __log2_imp> 64), 63>::value) + : __log2_imp::value; +}; + +#endif // _LIBCPP_HAS_NO_INT128 + +template +struct __log2 +{ + static const size_t value = __log2_imp< +#ifndef _LIBCPP_HAS_NO_INT128 + typename conditional< + sizeof(_UIntType) <= sizeof(unsigned long long), + unsigned long long, + __uint128_t + >::type, +#else + unsigned long long, +#endif // _LIBCPP_HAS_NO_INT128 + _Xp, sizeof(_UIntType) * __CHAR_BIT__ - 1>::value; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___RANDOM_LOG2_H diff --git a/contrib/llvm-project/libcxx/include/__random/lognormal_distribution.h b/contrib/llvm-project/libcxx/include/__random/lognormal_distribution.h new file mode 100644 index 000000000000..752861c3de0c --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/lognormal_distribution.h @@ -0,0 +1,163 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_LOGNORMAL_DISTRIBUTION_H +#define _LIBCPP___RANDOM_LOGNORMAL_DISTRIBUTION_H + +#include <__config> +#include <__random/normal_distribution.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS lognormal_distribution +{ +public: + // types + typedef _RealType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + normal_distribution __nd_; + public: + typedef lognormal_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(result_type __m = 0, result_type __s = 1) + : __nd_(__m, __s) {} + + _LIBCPP_INLINE_VISIBILITY + result_type m() const {return __nd_.mean();} + _LIBCPP_INLINE_VISIBILITY + result_type s() const {return __nd_.stddev();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__nd_ == __y.__nd_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + friend class lognormal_distribution; + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const lognormal_distribution<_RT>& __x); + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + lognormal_distribution<_RT>& __x); + }; + +private: + param_type __p_; + +public: + // constructor and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + lognormal_distribution() : lognormal_distribution(0) {} + _LIBCPP_INLINE_VISIBILITY + explicit lognormal_distribution(result_type __m, result_type __s = 1) + : __p_(param_type(__m, __s)) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit lognormal_distribution(result_type __m = 0, + result_type __s = 1) + : __p_(param_type(__m, __s)) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit lognormal_distribution(const param_type& __p) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {__p_.__nd_.reset();} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g, const param_type& __p) + {return _VSTD::exp(const_cast&>(__p.__nd_)(__g));} + + // property functions + _LIBCPP_INLINE_VISIBILITY + result_type m() const {return __p_.m();} + _LIBCPP_INLINE_VISIBILITY + result_type s() const {return __p_.s();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return 0;} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return numeric_limits::infinity();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const lognormal_distribution& __x, + const lognormal_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const lognormal_distribution& __x, + const lognormal_distribution& __y) + {return !(__x == __y);} + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const lognormal_distribution<_RT>& __x); + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + lognormal_distribution<_RT>& __x); +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const lognormal_distribution<_RT>& __x) +{ + return __os << __x.__p_.__nd_; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + lognormal_distribution<_RT>& __x) +{ + return __is >> __x.__p_.__nd_; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_LOGNORMAL_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/mersenne_twister_engine.h b/contrib/llvm-project/libcxx/include/__random/mersenne_twister_engine.h new file mode 100644 index 000000000000..121ffae37ec0 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/mersenne_twister_engine.h @@ -0,0 +1,534 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_MERSENNE_TWISTER_ENGINE_H +#define _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H + +#include <__algorithm/equal.h> +#include <__algorithm/min.h> +#include <__config> +#include <__random/is_seed_sequence.h> +#include +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS mersenne_twister_engine; + +template +bool +operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __x, + const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __y); + +template +_LIBCPP_INLINE_VISIBILITY +bool +operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __x, + const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __y); + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __x); + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __x); + +template +class _LIBCPP_TEMPLATE_VIS mersenne_twister_engine +{ +public: + // types + typedef _UIntType result_type; + +private: + result_type __x_[__n]; + size_t __i_; + + static_assert( 0 < __m, "mersenne_twister_engine invalid parameters"); + static_assert(__m <= __n, "mersenne_twister_engine invalid parameters"); + static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits::digits; + static_assert(__w <= _Dt, "mersenne_twister_engine invalid parameters"); + static_assert( 2 <= __w, "mersenne_twister_engine invalid parameters"); + static_assert(__r <= __w, "mersenne_twister_engine invalid parameters"); + static_assert(__u <= __w, "mersenne_twister_engine invalid parameters"); + static_assert(__s <= __w, "mersenne_twister_engine invalid parameters"); + static_assert(__t <= __w, "mersenne_twister_engine invalid parameters"); + static_assert(__l <= __w, "mersenne_twister_engine invalid parameters"); +public: + static _LIBCPP_CONSTEXPR const result_type _Min = 0; + static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) : + (result_type(1) << __w) - result_type(1); + static_assert(_Min < _Max, "mersenne_twister_engine invalid parameters"); + static_assert(__a <= _Max, "mersenne_twister_engine invalid parameters"); + static_assert(__b <= _Max, "mersenne_twister_engine invalid parameters"); + static_assert(__c <= _Max, "mersenne_twister_engine invalid parameters"); + static_assert(__d <= _Max, "mersenne_twister_engine invalid parameters"); + static_assert(__f <= _Max, "mersenne_twister_engine invalid parameters"); + + // engine characteristics + static _LIBCPP_CONSTEXPR const size_t word_size = __w; + static _LIBCPP_CONSTEXPR const size_t state_size = __n; + static _LIBCPP_CONSTEXPR const size_t shift_size = __m; + static _LIBCPP_CONSTEXPR const size_t mask_bits = __r; + static _LIBCPP_CONSTEXPR const result_type xor_mask = __a; + static _LIBCPP_CONSTEXPR const size_t tempering_u = __u; + static _LIBCPP_CONSTEXPR const result_type tempering_d = __d; + static _LIBCPP_CONSTEXPR const size_t tempering_s = __s; + static _LIBCPP_CONSTEXPR const result_type tempering_b = __b; + static _LIBCPP_CONSTEXPR const size_t tempering_t = __t; + static _LIBCPP_CONSTEXPR const result_type tempering_c = __c; + static _LIBCPP_CONSTEXPR const size_t tempering_l = __l; + static _LIBCPP_CONSTEXPR const result_type initialization_multiplier = __f; + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR result_type min() { return _Min; } + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR result_type max() { return _Max; } + static _LIBCPP_CONSTEXPR const result_type default_seed = 5489u; + + // constructors and seeding functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + mersenne_twister_engine() : mersenne_twister_engine(default_seed) {} + _LIBCPP_INLINE_VISIBILITY + explicit mersenne_twister_engine(result_type __sd) { seed(__sd); } +#else + _LIBCPP_INLINE_VISIBILITY + explicit mersenne_twister_engine(result_type __sd = default_seed) { + seed(__sd); + } +#endif + template + _LIBCPP_INLINE_VISIBILITY + explicit mersenne_twister_engine(_Sseq& __q, + typename enable_if<__is_seed_sequence<_Sseq, mersenne_twister_engine>::value>::type* = 0) + {seed(__q);} + void seed(result_type __sd = default_seed); + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + __is_seed_sequence<_Sseq, mersenne_twister_engine>::value, + void + >::type + seed(_Sseq& __q) + {__seed(__q, integral_constant());} + + // generating functions + result_type operator()(); + _LIBCPP_INLINE_VISIBILITY + void discard(unsigned long long __z) {for (; __z; --__z) operator()();} + + template + friend + bool + operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __x, + const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __y); + + template + friend + bool + operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __x, + const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __y); + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __x); + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __x); +private: + + template + void __seed(_Sseq& __q, integral_constant); + template + void __seed(_Sseq& __q, integral_constant); + + template + _LIBCPP_INLINE_VISIBILITY + static + typename enable_if + < + __count < __w, + result_type + >::type + __lshift(result_type __x) {return (__x << __count) & _Max;} + + template + _LIBCPP_INLINE_VISIBILITY + static + typename enable_if + < + (__count >= __w), + result_type + >::type + __lshift(result_type) {return result_type(0);} + + template + _LIBCPP_INLINE_VISIBILITY + static + typename enable_if + < + __count < _Dt, + result_type + >::type + __rshift(result_type __x) {return __x >> __count;} + + template + _LIBCPP_INLINE_VISIBILITY + static + typename enable_if + < + (__count >= _Dt), + result_type + >::type + __rshift(result_type) {return result_type(0);} +}; + +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::word_size; + +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::state_size; + +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::shift_size; + +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::mask_bits; + +template + _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::xor_mask; + +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_u; + +template + _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_d; + +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_s; + +template + _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_b; + +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_t; + +template + _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_c; + +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_l; + +template + _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::initialization_multiplier; + +template + _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::default_seed; + +template +void +mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, + __t, __c, __l, __f>::seed(result_type __sd) + _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK +{ // __w >= 2 + __x_[0] = __sd & _Max; + for (size_t __i = 1; __i < __n; ++__i) + __x_[__i] = (__f * (__x_[__i-1] ^ __rshift<__w - 2>(__x_[__i-1])) + __i) & _Max; + __i_ = 0; +} + +template +template +void +mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, + __t, __c, __l, __f>::__seed(_Sseq& __q, integral_constant) +{ + const unsigned __k = 1; + uint32_t __ar[__n * __k]; + __q.generate(__ar, __ar + __n * __k); + for (size_t __i = 0; __i < __n; ++__i) + __x_[__i] = static_cast(__ar[__i] & _Max); + const result_type __mask = __r == _Dt ? result_type(~0) : + (result_type(1) << __r) - result_type(1); + __i_ = 0; + if ((__x_[0] & ~__mask) == 0) + { + for (size_t __i = 1; __i < __n; ++__i) + if (__x_[__i] != 0) + return; + __x_[0] = result_type(1) << (__w - 1); + } +} + +template +template +void +mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, + __t, __c, __l, __f>::__seed(_Sseq& __q, integral_constant) +{ + const unsigned __k = 2; + uint32_t __ar[__n * __k]; + __q.generate(__ar, __ar + __n * __k); + for (size_t __i = 0; __i < __n; ++__i) + __x_[__i] = static_cast( + (__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max); + const result_type __mask = __r == _Dt ? result_type(~0) : + (result_type(1) << __r) - result_type(1); + __i_ = 0; + if ((__x_[0] & ~__mask) == 0) + { + for (size_t __i = 1; __i < __n; ++__i) + if (__x_[__i] != 0) + return; + __x_[0] = result_type(1) << (__w - 1); + } +} + +template +_UIntType +mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, + __t, __c, __l, __f>::operator()() +{ + const size_t __j = (__i_ + 1) % __n; + const result_type __mask = __r == _Dt ? result_type(~0) : + (result_type(1) << __r) - result_type(1); + const result_type _Yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask); + const size_t __k = (__i_ + __m) % __n; + __x_[__i_] = __x_[__k] ^ __rshift<1>(_Yp) ^ (__a * (_Yp & 1)); + result_type __z = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d); + __i_ = __j; + __z ^= __lshift<__s>(__z) & __b; + __z ^= __lshift<__t>(__z) & __c; + return __z ^ __rshift<__l>(__z); +} + +template +bool +operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __x, + const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __y) +{ + if (__x.__i_ == __y.__i_) + return _VSTD::equal(__x.__x_, __x.__x_ + _Np, __y.__x_); + if (__x.__i_ == 0 || __y.__i_ == 0) + { + size_t __j = _VSTD::min(_Np - __x.__i_, _Np - __y.__i_); + if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + __x.__i_ + __j, + __y.__x_ + __y.__i_)) + return false; + if (__x.__i_ == 0) + return _VSTD::equal(__x.__x_ + __j, __x.__x_ + _Np, __y.__x_); + return _VSTD::equal(__x.__x_, __x.__x_ + (_Np - __j), __y.__x_ + __j); + } + if (__x.__i_ < __y.__i_) + { + size_t __j = _Np - __y.__i_; + if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + (__x.__i_ + __j), + __y.__x_ + __y.__i_)) + return false; + if (!_VSTD::equal(__x.__x_ + (__x.__i_ + __j), __x.__x_ + _Np, + __y.__x_)) + return false; + return _VSTD::equal(__x.__x_, __x.__x_ + __x.__i_, + __y.__x_ + (_Np - (__x.__i_ + __j))); + } + size_t __j = _Np - __x.__i_; + if (!_VSTD::equal(__y.__x_ + __y.__i_, __y.__x_ + (__y.__i_ + __j), + __x.__x_ + __x.__i_)) + return false; + if (!_VSTD::equal(__y.__x_ + (__y.__i_ + __j), __y.__x_ + _Np, + __x.__x_)) + return false; + return _VSTD::equal(__y.__x_, __y.__x_ + __y.__i_, + __x.__x_ + (_Np - (__y.__i_ + __j))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __x, + const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __y) +{ + return !(__x == __y); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _Ostream; + __os.flags(_Ostream::dec | _Ostream::left); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + __os << __x.__x_[__x.__i_]; + for (size_t __j = __x.__i_ + 1; __j < _Np; ++__j) + __os << __sp << __x.__x_[__j]; + for (size_t __j = 0; __j < __x.__i_; ++__j) + __os << __sp << __x.__x_[__j]; + return __os; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, + _Bp, _Tp, _Cp, _Lp, _Fp>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + _UInt __t[_Np]; + for (size_t __i = 0; __i < _Np; ++__i) + __is >> __t[__i]; + if (!__is.fail()) + { + for (size_t __i = 0; __i < _Np; ++__i) + __x.__x_[__i] = __t[__i]; + __x.__i_ = 0; + } + return __is; +} + +typedef mersenne_twister_engine mt19937; +typedef mersenne_twister_engine mt19937_64; + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H diff --git a/contrib/llvm-project/libcxx/include/__random/negative_binomial_distribution.h b/contrib/llvm-project/libcxx/include/__random/negative_binomial_distribution.h new file mode 100644 index 000000000000..7329bac2ff85 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/negative_binomial_distribution.h @@ -0,0 +1,176 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_NEGATIVE_BINOMIAL_DISTRIBUTION_H +#define _LIBCPP___RANDOM_NEGATIVE_BINOMIAL_DISTRIBUTION_H + +#include <__config> +#include <__random/bernoulli_distribution.h> +#include <__random/gamma_distribution.h> +#include <__random/poisson_distribution.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS negative_binomial_distribution +{ +public: + // types + typedef _IntType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + result_type __k_; + double __p_; + public: + typedef negative_binomial_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(result_type __k = 1, double __p = 0.5) + : __k_(__k), __p_(__p) {} + + _LIBCPP_INLINE_VISIBILITY + result_type k() const {return __k_;} + _LIBCPP_INLINE_VISIBILITY + double p() const {return __p_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__k_ == __y.__k_ && __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + +public: + // constructor and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + negative_binomial_distribution() : negative_binomial_distribution(1) {} + _LIBCPP_INLINE_VISIBILITY + explicit negative_binomial_distribution(result_type __k, double __p = 0.5) + : __p_(__k, __p) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit negative_binomial_distribution(result_type __k = 1, + double __p = 0.5) + : __p_(__k, __p) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit negative_binomial_distribution(const param_type& __p) : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + _LIBCPP_INLINE_VISIBILITY + result_type k() const {return __p_.k();} + _LIBCPP_INLINE_VISIBILITY + double p() const {return __p_.p();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return 0;} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return numeric_limits::max();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const negative_binomial_distribution& __x, + const negative_binomial_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const negative_binomial_distribution& __x, + const negative_binomial_distribution& __y) + {return !(__x == __y);} +}; + +template +template +_IntType +negative_binomial_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr) +{ + result_type __k = __pr.k(); + double __p = __pr.p(); + if (__k <= 21 * __p) + { + bernoulli_distribution __gen(__p); + result_type __f = 0; + result_type __s = 0; + while (__s < __k) + { + if (__gen(__urng)) + ++__s; + else + ++__f; + } + return __f; + } + return poisson_distribution(gamma_distribution + (__k, (1-__p)/__p)(__urng))(__urng); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const negative_binomial_distribution<_IntType>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + return __os << __x.k() << __sp << __x.p(); +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + negative_binomial_distribution<_IntType>& __x) +{ + typedef negative_binomial_distribution<_IntType> _Eng; + typedef typename _Eng::result_type result_type; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + result_type __k; + double __p; + __is >> __k >> __p; + if (!__is.fail()) + __x.param(param_type(__k, __p)); + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_NEGATIVE_BINOMIAL_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/normal_distribution.h b/contrib/llvm-project/libcxx/include/__random/normal_distribution.h new file mode 100644 index 000000000000..b460ffb7ea9d --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/normal_distribution.h @@ -0,0 +1,208 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_NORMAL_DISTRIBUTION_H +#define _LIBCPP___RANDOM_NORMAL_DISTRIBUTION_H + +#include <__config> +#include <__random/uniform_real_distribution.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS normal_distribution +{ +public: + // types + typedef _RealType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + result_type __mean_; + result_type __stddev_; + public: + typedef normal_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(result_type __mean = 0, result_type __stddev = 1) + : __mean_(__mean), __stddev_(__stddev) {} + + _LIBCPP_INLINE_VISIBILITY + result_type mean() const {return __mean_;} + _LIBCPP_INLINE_VISIBILITY + result_type stddev() const {return __stddev_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__mean_ == __y.__mean_ && __x.__stddev_ == __y.__stddev_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + result_type _V_; + bool _V_hot_; + +public: + // constructors and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + normal_distribution() : normal_distribution(0) {} + _LIBCPP_INLINE_VISIBILITY + explicit normal_distribution(result_type __mean, result_type __stddev = 1) + : __p_(param_type(__mean, __stddev)), _V_hot_(false) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit normal_distribution(result_type __mean = 0, + result_type __stddev = 1) + : __p_(param_type(__mean, __stddev)), _V_hot_(false) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit normal_distribution(const param_type& __p) + : __p_(__p), _V_hot_(false) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {_V_hot_ = false;} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + _LIBCPP_INLINE_VISIBILITY + result_type mean() const {return __p_.mean();} + _LIBCPP_INLINE_VISIBILITY + result_type stddev() const {return __p_.stddev();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return -numeric_limits::infinity();} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return numeric_limits::infinity();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const normal_distribution& __x, + const normal_distribution& __y) + {return __x.__p_ == __y.__p_ && __x._V_hot_ == __y._V_hot_ && + (!__x._V_hot_ || __x._V_ == __y._V_);} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const normal_distribution& __x, + const normal_distribution& __y) + {return !(__x == __y);} + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const normal_distribution<_RT>& __x); + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + normal_distribution<_RT>& __x); +}; + +template +template +_RealType +normal_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) +{ + result_type _Up; + if (_V_hot_) + { + _V_hot_ = false; + _Up = _V_; + } + else + { + uniform_real_distribution _Uni(-1, 1); + result_type __u; + result_type __v; + result_type __s; + do + { + __u = _Uni(__g); + __v = _Uni(__g); + __s = __u * __u + __v * __v; + } while (__s > 1 || __s == 0); + result_type _Fp = _VSTD::sqrt(-2 * _VSTD::log(__s) / __s); + _V_ = __v * _Fp; + _V_hot_ = true; + _Up = __u * _Fp; + } + return _Up * __p.stddev() + __p.mean(); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const normal_distribution<_RT>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + __os << __x.mean() << __sp << __x.stddev() << __sp << __x._V_hot_; + if (__x._V_hot_) + __os << __sp << __x._V_; + return __os; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + normal_distribution<_RT>& __x) +{ + typedef normal_distribution<_RT> _Eng; + typedef typename _Eng::result_type result_type; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + result_type __mean; + result_type __stddev; + result_type _Vp = 0; + bool _V_hot = false; + __is >> __mean >> __stddev >> _V_hot; + if (_V_hot) + __is >> _Vp; + if (!__is.fail()) + { + __x.param(param_type(__mean, __stddev)); + __x._V_hot_ = _V_hot; + __x._V_ = _Vp; + } + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_NORMAL_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/piecewise_constant_distribution.h b/contrib/llvm-project/libcxx/include/__random/piecewise_constant_distribution.h new file mode 100644 index 000000000000..ece20d1a1d6e --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/piecewise_constant_distribution.h @@ -0,0 +1,356 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_H +#define _LIBCPP___RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_H + +#include <__algorithm/upper_bound.h> +#include <__config> +#include <__random/uniform_real_distribution.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS piecewise_constant_distribution +{ +public: + // types + typedef _RealType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + vector __b_; + vector __densities_; + vector __areas_; + public: + typedef piecewise_constant_distribution distribution_type; + + param_type(); + template + param_type(_InputIteratorB __fB, _InputIteratorB __lB, + _InputIteratorW __fW); +#ifndef _LIBCPP_CXX03_LANG + template + param_type(initializer_list __bl, _UnaryOperation __fw); +#endif // _LIBCPP_CXX03_LANG + template + param_type(size_t __nw, result_type __xmin, result_type __xmax, + _UnaryOperation __fw); + param_type(param_type const&) = default; + param_type & operator=(const param_type& __rhs); + + _LIBCPP_INLINE_VISIBILITY + vector intervals() const {return __b_;} + _LIBCPP_INLINE_VISIBILITY + vector densities() const {return __densities_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__densities_ == __y.__densities_ && __x.__b_ == __y.__b_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + + private: + void __init(); + + friend class piecewise_constant_distribution; + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const piecewise_constant_distribution<_RT>& __x); + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + piecewise_constant_distribution<_RT>& __x); + }; + +private: + param_type __p_; + +public: + // constructor and reset functions + _LIBCPP_INLINE_VISIBILITY + piecewise_constant_distribution() {} + template + _LIBCPP_INLINE_VISIBILITY + piecewise_constant_distribution(_InputIteratorB __fB, + _InputIteratorB __lB, + _InputIteratorW __fW) + : __p_(__fB, __lB, __fW) {} + +#ifndef _LIBCPP_CXX03_LANG + template + _LIBCPP_INLINE_VISIBILITY + piecewise_constant_distribution(initializer_list __bl, + _UnaryOperation __fw) + : __p_(__bl, __fw) {} +#endif // _LIBCPP_CXX03_LANG + + template + _LIBCPP_INLINE_VISIBILITY + piecewise_constant_distribution(size_t __nw, result_type __xmin, + result_type __xmax, _UnaryOperation __fw) + : __p_(__nw, __xmin, __xmax, __fw) {} + + _LIBCPP_INLINE_VISIBILITY + explicit piecewise_constant_distribution(const param_type& __p) + : __p_(__p) {} + + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + _LIBCPP_INLINE_VISIBILITY + vector intervals() const {return __p_.intervals();} + _LIBCPP_INLINE_VISIBILITY + vector densities() const {return __p_.densities();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return __p_.__b_.front();} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return __p_.__b_.back();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const piecewise_constant_distribution& __x, + const piecewise_constant_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const piecewise_constant_distribution& __x, + const piecewise_constant_distribution& __y) + {return !(__x == __y);} + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const piecewise_constant_distribution<_RT>& __x); + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + piecewise_constant_distribution<_RT>& __x); +}; + +template +typename piecewise_constant_distribution<_RealType>::param_type & +piecewise_constant_distribution<_RealType>::param_type::operator= + (const param_type& __rhs) +{ +// These can throw + __b_.reserve (__rhs.__b_.size ()); + __densities_.reserve(__rhs.__densities_.size()); + __areas_.reserve (__rhs.__areas_.size()); + +// These can not throw + __b_ = __rhs.__b_; + __densities_ = __rhs.__densities_; + __areas_ = __rhs.__areas_; + return *this; +} + +template +void +piecewise_constant_distribution<_RealType>::param_type::__init() +{ + // __densities_ contains non-normalized areas + result_type __total_area = _VSTD::accumulate(__densities_.begin(), + __densities_.end(), + result_type()); + for (size_t __i = 0; __i < __densities_.size(); ++__i) + __densities_[__i] /= __total_area; + // __densities_ contains normalized areas + __areas_.assign(__densities_.size(), result_type()); + _VSTD::partial_sum(__densities_.begin(), __densities_.end() - 1, + __areas_.begin() + 1); + // __areas_ contains partial sums of normalized areas: [0, __densities_ - 1] + __densities_.back() = 1 - __areas_.back(); // correct round off error + for (size_t __i = 0; __i < __densities_.size(); ++__i) + __densities_[__i] /= (__b_[__i+1] - __b_[__i]); + // __densities_ now contains __densities_ +} + +template +piecewise_constant_distribution<_RealType>::param_type::param_type() + : __b_(2), + __densities_(1, 1.0), + __areas_(1, 0.0) +{ + __b_[1] = 1; +} + +template +template +piecewise_constant_distribution<_RealType>::param_type::param_type( + _InputIteratorB __fB, _InputIteratorB __lB, _InputIteratorW __fW) + : __b_(__fB, __lB) +{ + if (__b_.size() < 2) + { + __b_.resize(2); + __b_[0] = 0; + __b_[1] = 1; + __densities_.assign(1, 1.0); + __areas_.assign(1, 0.0); + } + else + { + __densities_.reserve(__b_.size() - 1); + for (size_t __i = 0; __i < __b_.size() - 1; ++__i, ++__fW) + __densities_.push_back(*__fW); + __init(); + } +} + +#ifndef _LIBCPP_CXX03_LANG + +template +template +piecewise_constant_distribution<_RealType>::param_type::param_type( + initializer_list __bl, _UnaryOperation __fw) + : __b_(__bl.begin(), __bl.end()) +{ + if (__b_.size() < 2) + { + __b_.resize(2); + __b_[0] = 0; + __b_[1] = 1; + __densities_.assign(1, 1.0); + __areas_.assign(1, 0.0); + } + else + { + __densities_.reserve(__b_.size() - 1); + for (size_t __i = 0; __i < __b_.size() - 1; ++__i) + __densities_.push_back(__fw((__b_[__i+1] + __b_[__i])*.5)); + __init(); + } +} + +#endif // _LIBCPP_CXX03_LANG + +template +template +piecewise_constant_distribution<_RealType>::param_type::param_type( + size_t __nw, result_type __xmin, result_type __xmax, _UnaryOperation __fw) + : __b_(__nw == 0 ? 2 : __nw + 1) +{ + size_t __n = __b_.size() - 1; + result_type __d = (__xmax - __xmin) / __n; + __densities_.reserve(__n); + for (size_t __i = 0; __i < __n; ++__i) + { + __b_[__i] = __xmin + __i * __d; + __densities_.push_back(__fw(__b_[__i] + __d*.5)); + } + __b_[__n] = __xmax; + __init(); +} + +template +template +_RealType +piecewise_constant_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) +{ + typedef uniform_real_distribution _Gen; + result_type __u = _Gen()(__g); + ptrdiff_t __k = _VSTD::upper_bound(__p.__areas_.begin(), __p.__areas_.end(), + __u) - __p.__areas_.begin() - 1; + return (__u - __p.__areas_[__k]) / __p.__densities_[__k] + __p.__b_[__k]; +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const piecewise_constant_distribution<_RT>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + size_t __n = __x.__p_.__b_.size(); + __os << __n; + for (size_t __i = 0; __i < __n; ++__i) + __os << __sp << __x.__p_.__b_[__i]; + __n = __x.__p_.__densities_.size(); + __os << __sp << __n; + for (size_t __i = 0; __i < __n; ++__i) + __os << __sp << __x.__p_.__densities_[__i]; + __n = __x.__p_.__areas_.size(); + __os << __sp << __n; + for (size_t __i = 0; __i < __n; ++__i) + __os << __sp << __x.__p_.__areas_[__i]; + return __os; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + piecewise_constant_distribution<_RT>& __x) +{ + typedef piecewise_constant_distribution<_RT> _Eng; + typedef typename _Eng::result_type result_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + size_t __n; + __is >> __n; + vector __b(__n); + for (size_t __i = 0; __i < __n; ++__i) + __is >> __b[__i]; + __is >> __n; + vector __densities(__n); + for (size_t __i = 0; __i < __n; ++__i) + __is >> __densities[__i]; + __is >> __n; + vector __areas(__n); + for (size_t __i = 0; __i < __n; ++__i) + __is >> __areas[__i]; + if (!__is.fail()) + { + swap(__x.__p_.__b_, __b); + swap(__x.__p_.__densities_, __densities); + swap(__x.__p_.__areas_, __areas); + } + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/piecewise_linear_distribution.h b/contrib/llvm-project/libcxx/include/__random/piecewise_linear_distribution.h new file mode 100644 index 000000000000..b2ba164d0707 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/piecewise_linear_distribution.h @@ -0,0 +1,372 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_H +#define _LIBCPP___RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_H + +#include <__algorithm/upper_bound.h> +#include <__config> +#include <__random/uniform_real_distribution.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS piecewise_linear_distribution +{ +public: + // types + typedef _RealType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + vector __b_; + vector __densities_; + vector __areas_; + public: + typedef piecewise_linear_distribution distribution_type; + + param_type(); + template + param_type(_InputIteratorB __fB, _InputIteratorB __lB, + _InputIteratorW __fW); +#ifndef _LIBCPP_CXX03_LANG + template + param_type(initializer_list __bl, _UnaryOperation __fw); +#endif // _LIBCPP_CXX03_LANG + template + param_type(size_t __nw, result_type __xmin, result_type __xmax, + _UnaryOperation __fw); + param_type(param_type const&) = default; + param_type & operator=(const param_type& __rhs); + + _LIBCPP_INLINE_VISIBILITY + vector intervals() const {return __b_;} + _LIBCPP_INLINE_VISIBILITY + vector densities() const {return __densities_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__densities_ == __y.__densities_ && __x.__b_ == __y.__b_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + + private: + void __init(); + + friend class piecewise_linear_distribution; + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const piecewise_linear_distribution<_RT>& __x); + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + piecewise_linear_distribution<_RT>& __x); + }; + +private: + param_type __p_; + +public: + // constructor and reset functions + _LIBCPP_INLINE_VISIBILITY + piecewise_linear_distribution() {} + template + _LIBCPP_INLINE_VISIBILITY + piecewise_linear_distribution(_InputIteratorB __fB, + _InputIteratorB __lB, + _InputIteratorW __fW) + : __p_(__fB, __lB, __fW) {} + +#ifndef _LIBCPP_CXX03_LANG + template + _LIBCPP_INLINE_VISIBILITY + piecewise_linear_distribution(initializer_list __bl, + _UnaryOperation __fw) + : __p_(__bl, __fw) {} +#endif // _LIBCPP_CXX03_LANG + + template + _LIBCPP_INLINE_VISIBILITY + piecewise_linear_distribution(size_t __nw, result_type __xmin, + result_type __xmax, _UnaryOperation __fw) + : __p_(__nw, __xmin, __xmax, __fw) {} + + _LIBCPP_INLINE_VISIBILITY + explicit piecewise_linear_distribution(const param_type& __p) + : __p_(__p) {} + + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + _LIBCPP_INLINE_VISIBILITY + vector intervals() const {return __p_.intervals();} + _LIBCPP_INLINE_VISIBILITY + vector densities() const {return __p_.densities();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return __p_.__b_.front();} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return __p_.__b_.back();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const piecewise_linear_distribution& __x, + const piecewise_linear_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const piecewise_linear_distribution& __x, + const piecewise_linear_distribution& __y) + {return !(__x == __y);} + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const piecewise_linear_distribution<_RT>& __x); + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + piecewise_linear_distribution<_RT>& __x); +}; + +template +typename piecewise_linear_distribution<_RealType>::param_type & +piecewise_linear_distribution<_RealType>::param_type::operator= + (const param_type& __rhs) +{ +// These can throw + __b_.reserve (__rhs.__b_.size ()); + __densities_.reserve(__rhs.__densities_.size()); + __areas_.reserve (__rhs.__areas_.size()); + +// These can not throw + __b_ = __rhs.__b_; + __densities_ = __rhs.__densities_; + __areas_ = __rhs.__areas_; + return *this; +} + + +template +void +piecewise_linear_distribution<_RealType>::param_type::__init() +{ + __areas_.assign(__densities_.size() - 1, result_type()); + result_type _Sp = 0; + for (size_t __i = 0; __i < __areas_.size(); ++__i) + { + __areas_[__i] = (__densities_[__i+1] + __densities_[__i]) * + (__b_[__i+1] - __b_[__i]) * .5; + _Sp += __areas_[__i]; + } + for (size_t __i = __areas_.size(); __i > 1;) + { + --__i; + __areas_[__i] = __areas_[__i-1] / _Sp; + } + __areas_[0] = 0; + for (size_t __i = 1; __i < __areas_.size(); ++__i) + __areas_[__i] += __areas_[__i-1]; + for (size_t __i = 0; __i < __densities_.size(); ++__i) + __densities_[__i] /= _Sp; +} + +template +piecewise_linear_distribution<_RealType>::param_type::param_type() + : __b_(2), + __densities_(2, 1.0), + __areas_(1, 0.0) +{ + __b_[1] = 1; +} + +template +template +piecewise_linear_distribution<_RealType>::param_type::param_type( + _InputIteratorB __fB, _InputIteratorB __lB, _InputIteratorW __fW) + : __b_(__fB, __lB) +{ + if (__b_.size() < 2) + { + __b_.resize(2); + __b_[0] = 0; + __b_[1] = 1; + __densities_.assign(2, 1.0); + __areas_.assign(1, 0.0); + } + else + { + __densities_.reserve(__b_.size()); + for (size_t __i = 0; __i < __b_.size(); ++__i, ++__fW) + __densities_.push_back(*__fW); + __init(); + } +} + +#ifndef _LIBCPP_CXX03_LANG + +template +template +piecewise_linear_distribution<_RealType>::param_type::param_type( + initializer_list __bl, _UnaryOperation __fw) + : __b_(__bl.begin(), __bl.end()) +{ + if (__b_.size() < 2) + { + __b_.resize(2); + __b_[0] = 0; + __b_[1] = 1; + __densities_.assign(2, 1.0); + __areas_.assign(1, 0.0); + } + else + { + __densities_.reserve(__b_.size()); + for (size_t __i = 0; __i < __b_.size(); ++__i) + __densities_.push_back(__fw(__b_[__i])); + __init(); + } +} + +#endif // _LIBCPP_CXX03_LANG + +template +template +piecewise_linear_distribution<_RealType>::param_type::param_type( + size_t __nw, result_type __xmin, result_type __xmax, _UnaryOperation __fw) + : __b_(__nw == 0 ? 2 : __nw + 1) +{ + size_t __n = __b_.size() - 1; + result_type __d = (__xmax - __xmin) / __n; + __densities_.reserve(__b_.size()); + for (size_t __i = 0; __i < __n; ++__i) + { + __b_[__i] = __xmin + __i * __d; + __densities_.push_back(__fw(__b_[__i])); + } + __b_[__n] = __xmax; + __densities_.push_back(__fw(__b_[__n])); + __init(); +} + +template +template +_RealType +piecewise_linear_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) +{ + typedef uniform_real_distribution _Gen; + result_type __u = _Gen()(__g); + ptrdiff_t __k = _VSTD::upper_bound(__p.__areas_.begin(), __p.__areas_.end(), + __u) - __p.__areas_.begin() - 1; + __u -= __p.__areas_[__k]; + const result_type __dk = __p.__densities_[__k]; + const result_type __dk1 = __p.__densities_[__k+1]; + const result_type __deltad = __dk1 - __dk; + const result_type __bk = __p.__b_[__k]; + if (__deltad == 0) + return __u / __dk + __bk; + const result_type __bk1 = __p.__b_[__k+1]; + const result_type __deltab = __bk1 - __bk; + return (__bk * __dk1 - __bk1 * __dk + + _VSTD::sqrt(__deltab * (__deltab * __dk * __dk + 2 * __deltad * __u))) / + __deltad; +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const piecewise_linear_distribution<_RT>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + size_t __n = __x.__p_.__b_.size(); + __os << __n; + for (size_t __i = 0; __i < __n; ++__i) + __os << __sp << __x.__p_.__b_[__i]; + __n = __x.__p_.__densities_.size(); + __os << __sp << __n; + for (size_t __i = 0; __i < __n; ++__i) + __os << __sp << __x.__p_.__densities_[__i]; + __n = __x.__p_.__areas_.size(); + __os << __sp << __n; + for (size_t __i = 0; __i < __n; ++__i) + __os << __sp << __x.__p_.__areas_[__i]; + return __os; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + piecewise_linear_distribution<_RT>& __x) +{ + typedef piecewise_linear_distribution<_RT> _Eng; + typedef typename _Eng::result_type result_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + size_t __n; + __is >> __n; + vector __b(__n); + for (size_t __i = 0; __i < __n; ++__i) + __is >> __b[__i]; + __is >> __n; + vector __densities(__n); + for (size_t __i = 0; __i < __n; ++__i) + __is >> __densities[__i]; + __is >> __n; + vector __areas(__n); + for (size_t __i = 0; __i < __n; ++__i) + __is >> __areas[__i]; + if (!__is.fail()) + { + swap(__x.__p_.__b_, __b); + swap(__x.__p_.__densities_, __densities); + swap(__x.__p_.__areas_, __areas); + } + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/poisson_distribution.h b/contrib/llvm-project/libcxx/include/__random/poisson_distribution.h new file mode 100644 index 000000000000..fb213b0103ad --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/poisson_distribution.h @@ -0,0 +1,276 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_POISSON_DISTRIBUTION_H +#define _LIBCPP___RANDOM_POISSON_DISTRIBUTION_H + +#include <__config> +#include <__random/exponential_distribution.h> +#include <__random/normal_distribution.h> +#include <__random/uniform_real_distribution.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS poisson_distribution +{ +public: + // types + typedef _IntType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + double __mean_; + double __s_; + double __d_; + double __l_; + double __omega_; + double __c0_; + double __c1_; + double __c2_; + double __c3_; + double __c_; + + public: + typedef poisson_distribution distribution_type; + + explicit param_type(double __mean = 1.0); + + _LIBCPP_INLINE_VISIBILITY + double mean() const {return __mean_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__mean_ == __y.__mean_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + + friend class poisson_distribution; + }; + +private: + param_type __p_; + +public: + // constructors and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + poisson_distribution() : poisson_distribution(1.0) {} + _LIBCPP_INLINE_VISIBILITY + explicit poisson_distribution(double __mean) + : __p_(__mean) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit poisson_distribution(double __mean = 1.0) + : __p_(__mean) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit poisson_distribution(const param_type& __p) : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + _LIBCPP_INLINE_VISIBILITY + double mean() const {return __p_.mean();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return 0;} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return numeric_limits::max();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const poisson_distribution& __x, + const poisson_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const poisson_distribution& __x, + const poisson_distribution& __y) + {return !(__x == __y);} +}; + +template +poisson_distribution<_IntType>::param_type::param_type(double __mean) + // According to the standard `inf` is a valid input, but it causes the + // distribution to hang, so we replace it with the maximum representable + // mean. + : __mean_(isinf(__mean) ? numeric_limits::max() : __mean) +{ + if (__mean_ < 10) + { + __s_ = 0; + __d_ = 0; + __l_ = _VSTD::exp(-__mean_); + __omega_ = 0; + __c3_ = 0; + __c2_ = 0; + __c1_ = 0; + __c0_ = 0; + __c_ = 0; + } + else + { + __s_ = _VSTD::sqrt(__mean_); + __d_ = 6 * __mean_ * __mean_; + __l_ = _VSTD::trunc(__mean_ - 1.1484); + __omega_ = .3989423 / __s_; + double __b1_ = .4166667E-1 / __mean_; + double __b2_ = .3 * __b1_ * __b1_; + __c3_ = .1428571 * __b1_ * __b2_; + __c2_ = __b2_ - 15. * __c3_; + __c1_ = __b1_ - 6. * __b2_ + 45. * __c3_; + __c0_ = 1. - __b1_ + 3. * __b2_ - 15. * __c3_; + __c_ = .1069 / __mean_; + } +} + +template +template +_IntType +poisson_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr) +{ + double __tx; + uniform_real_distribution __urd; + if (__pr.__mean_ < 10) + { + __tx = 0; + for (double __p = __urd(__urng); __p > __pr.__l_; ++__tx) + __p *= __urd(__urng); + } + else + { + double __difmuk; + double __g = __pr.__mean_ + __pr.__s_ * normal_distribution()(__urng); + double __u; + if (__g > 0) + { + __tx = _VSTD::trunc(__g); + if (__tx >= __pr.__l_) + return _VSTD::__clamp_to_integral(__tx); + __difmuk = __pr.__mean_ - __tx; + __u = __urd(__urng); + if (__pr.__d_ * __u >= __difmuk * __difmuk * __difmuk) + return _VSTD::__clamp_to_integral(__tx); + } + exponential_distribution __edist; + for (bool __using_exp_dist = false; true; __using_exp_dist = true) + { + double __e; + if (__using_exp_dist || __g <= 0) + { + double __t; + do + { + __e = __edist(__urng); + __u = __urd(__urng); + __u += __u - 1; + __t = 1.8 + (__u < 0 ? -__e : __e); + } while (__t <= -.6744); + __tx = _VSTD::trunc(__pr.__mean_ + __pr.__s_ * __t); + __difmuk = __pr.__mean_ - __tx; + __using_exp_dist = true; + } + double __px; + double __py; + if (__tx < 10 && __tx >= 0) + { + const double __fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, + 40320, 362880}; + __px = -__pr.__mean_; + __py = _VSTD::pow(__pr.__mean_, (double)__tx) / __fac[static_cast(__tx)]; + } + else + { + double __del = .8333333E-1 / __tx; + __del -= 4.8 * __del * __del * __del; + double __v = __difmuk / __tx; + if (_VSTD::abs(__v) > 0.25) + __px = __tx * _VSTD::log(1 + __v) - __difmuk - __del; + else + __px = __tx * __v * __v * (((((((.1250060 * __v + -.1384794) * + __v + .1421878) * __v + -.1661269) * __v + .2000118) * + __v + -.2500068) * __v + .3333333) * __v + -.5) - __del; + __py = .3989423 / _VSTD::sqrt(__tx); + } + double __r = (0.5 - __difmuk) / __pr.__s_; + double __r2 = __r * __r; + double __fx = -0.5 * __r2; + double __fy = __pr.__omega_ * (((__pr.__c3_ * __r2 + __pr.__c2_) * + __r2 + __pr.__c1_) * __r2 + __pr.__c0_); + if (__using_exp_dist) + { + if (__pr.__c_ * _VSTD::abs(__u) <= __py * _VSTD::exp(__px + __e) - + __fy * _VSTD::exp(__fx + __e)) + break; + } + else + { + if (__fy - __u * __fy <= __py * _VSTD::exp(__px - __fx)) + break; + } + } + } + return _VSTD::__clamp_to_integral(__tx); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const poisson_distribution<_IntType>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + return __os << __x.mean(); +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + poisson_distribution<_IntType>& __x) +{ + typedef poisson_distribution<_IntType> _Eng; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + double __mean; + __is >> __mean; + if (!__is.fail()) + __x.param(param_type(__mean)); + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_POISSON_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/random_device.h b/contrib/llvm-project/libcxx/include/__random/random_device.h new file mode 100644 index 000000000000..f62f7a3d269b --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/random_device.h @@ -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___RANDOM_RANDOM_DEVICE_H +#define _LIBCPP___RANDOM_RANDOM_DEVICE_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANDOM_DEVICE) + +class _LIBCPP_TYPE_VIS random_device +{ +#ifdef _LIBCPP_USING_DEV_RANDOM + int __f_; +#endif // defined(_LIBCPP_USING_DEV_RANDOM) +public: + // types + typedef unsigned result_type; + + // generator characteristics + static _LIBCPP_CONSTEXPR const result_type _Min = 0; + static _LIBCPP_CONSTEXPR const result_type _Max = 0xFFFFFFFFu; + + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR result_type min() { return _Min;} + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR result_type max() { return _Max;} + + // constructors +#ifndef _LIBCPP_CXX03_LANG + random_device() : random_device("/dev/urandom") {} + explicit random_device(const string& __token); +#else + explicit random_device(const string& __token = "/dev/urandom"); +#endif + ~random_device(); + + // generating functions + result_type operator()(); + + // property functions + double entropy() const _NOEXCEPT; + +private: + // no copy functions + random_device(const random_device&); // = delete; + random_device& operator=(const random_device&); // = delete; +}; + +#endif // !_LIBCPP_HAS_NO_RANDOM_DEVICE + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_RANDOM_DEVICE_H diff --git a/contrib/llvm-project/libcxx/include/__random/ranlux.h b/contrib/llvm-project/libcxx/include/__random/ranlux.h new file mode 100644 index 000000000000..0b415928df4d --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/ranlux.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___RANDOM_RANLUX_H +#define _LIBCPP___RANDOM_RANLUX_H + +#include <__config> +#include <__random/discard_block_engine.h> +#include <__random/subtract_with_carry_engine.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +typedef subtract_with_carry_engine ranlux24_base; +typedef subtract_with_carry_engine ranlux48_base; + +typedef discard_block_engine ranlux24; +typedef discard_block_engine ranlux48; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___RANDOM_RANLUX_H diff --git a/contrib/llvm-project/libcxx/include/__random/seed_seq.h b/contrib/llvm-project/libcxx/include/__random/seed_seq.h new file mode 100644 index 000000000000..97bc88d0d4d1 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/seed_seq.h @@ -0,0 +1,150 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_SEED_SEQ_H +#define _LIBCPP___RANDOM_SEED_SEQ_H + +#include <__algorithm/copy.h> +#include <__algorithm/fill.h> +#include <__algorithm/max.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +class _LIBCPP_TEMPLATE_VIS seed_seq +{ +public: + // types + typedef uint32_t result_type; + +private: + vector __v_; + + template + void init(_InputIterator __first, _InputIterator __last); +public: + // constructors + _LIBCPP_INLINE_VISIBILITY + seed_seq() _NOEXCEPT {} +#ifndef _LIBCPP_CXX03_LANG + template + _LIBCPP_INLINE_VISIBILITY + seed_seq(initializer_list<_Tp> __il) {init(__il.begin(), __il.end());} +#endif // _LIBCPP_CXX03_LANG + + template + _LIBCPP_INLINE_VISIBILITY + seed_seq(_InputIterator __first, _InputIterator __last) + {init(__first, __last);} + + // generating functions + template + void generate(_RandomAccessIterator __first, _RandomAccessIterator __last); + + // property functions + _LIBCPP_INLINE_VISIBILITY + size_t size() const _NOEXCEPT {return __v_.size();} + template + _LIBCPP_INLINE_VISIBILITY + void param(_OutputIterator __dest) const + {_VSTD::copy(__v_.begin(), __v_.end(), __dest);} + +private: + // no copy functions + seed_seq(const seed_seq&); // = delete; + void operator=(const seed_seq&); // = delete; + + _LIBCPP_INLINE_VISIBILITY + static result_type _Tp(result_type __x) {return __x ^ (__x >> 27);} +}; + +template +void +seed_seq::init(_InputIterator __first, _InputIterator __last) +{ + for (_InputIterator __s = __first; __s != __last; ++__s) + __v_.push_back(*__s & 0xFFFFFFFF); +} + +template +void +seed_seq::generate(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + if (__first != __last) + { + _VSTD::fill(__first, __last, 0x8b8b8b8b); + const size_t __n = static_cast(__last - __first); + const size_t __s = __v_.size(); + const size_t __t = (__n >= 623) ? 11 + : (__n >= 68) ? 7 + : (__n >= 39) ? 5 + : (__n >= 7) ? 3 + : (__n - 1) / 2; + const size_t __p = (__n - __t) / 2; + const size_t __q = __p + __t; + const size_t __m = _VSTD::max(__s + 1, __n); + // __k = 0; + { + result_type __r = 1664525 * _Tp(__first[0] ^ __first[__p] + ^ __first[__n - 1]); + __first[__p] += __r; + __r += __s; + __first[__q] += __r; + __first[0] = __r; + } + for (size_t __k = 1; __k <= __s; ++__k) + { + const size_t __kmodn = __k % __n; + const size_t __kpmodn = (__k + __p) % __n; + result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn] + ^ __first[(__k - 1) % __n]); + __first[__kpmodn] += __r; + __r += __kmodn + __v_[__k-1]; + __first[(__k + __q) % __n] += __r; + __first[__kmodn] = __r; + } + for (size_t __k = __s + 1; __k < __m; ++__k) + { + const size_t __kmodn = __k % __n; + const size_t __kpmodn = (__k + __p) % __n; + result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn] + ^ __first[(__k - 1) % __n]); + __first[__kpmodn] += __r; + __r += __kmodn; + __first[(__k + __q) % __n] += __r; + __first[__kmodn] = __r; + } + for (size_t __k = __m; __k < __m + __n; ++__k) + { + const size_t __kmodn = __k % __n; + const size_t __kpmodn = (__k + __p) % __n; + result_type __r = 1566083941 * _Tp(__first[__kmodn] + + __first[__kpmodn] + + __first[(__k - 1) % __n]); + __first[__kpmodn] ^= __r; + __r -= __kmodn; + __first[(__k + __q) % __n] ^= __r; + __first[__kmodn] = __r; + } + } +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_SEED_SEQ_H diff --git a/contrib/llvm-project/libcxx/include/__random/shuffle_order_engine.h b/contrib/llvm-project/libcxx/include/__random/shuffle_order_engine.h new file mode 100644 index 000000000000..7a5735dd7933 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/shuffle_order_engine.h @@ -0,0 +1,283 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_SHUFFLE_ORDER_ENGINE_H +#define _LIBCPP___RANDOM_SHUFFLE_ORDER_ENGINE_H + +#include <__algorithm/equal.h> +#include <__config> +#include <__random/is_seed_sequence.h> +#include <__utility/move.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __ugcd +{ + static _LIBCPP_CONSTEXPR const uint64_t value = __ugcd<_Yp, _Xp % _Yp>::value; +}; + +template +struct __ugcd<_Xp, 0> +{ + static _LIBCPP_CONSTEXPR const uint64_t value = _Xp; +}; + +template +class __uratio +{ + static_assert(_Dp != 0, "__uratio divide by 0"); + static _LIBCPP_CONSTEXPR const uint64_t __gcd = __ugcd<_Np, _Dp>::value; +public: + static _LIBCPP_CONSTEXPR const uint64_t num = _Np / __gcd; + static _LIBCPP_CONSTEXPR const uint64_t den = _Dp / __gcd; + + typedef __uratio type; +}; + +template +class _LIBCPP_TEMPLATE_VIS shuffle_order_engine +{ + static_assert(0 < __k, "shuffle_order_engine invalid parameters"); +public: + // types + typedef typename _Engine::result_type result_type; + +private: + _Engine __e_; + result_type _V_[__k]; + result_type _Y_; + +public: + // engine characteristics + static _LIBCPP_CONSTEXPR const size_t table_size = __k; + +#ifdef _LIBCPP_CXX03_LANG + static const result_type _Min = _Engine::_Min; + static const result_type _Max = _Engine::_Max; +#else + static _LIBCPP_CONSTEXPR const result_type _Min = _Engine::min(); + static _LIBCPP_CONSTEXPR const result_type _Max = _Engine::max(); +#endif + static_assert(_Min < _Max, "shuffle_order_engine invalid parameters"); + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR result_type min() { return _Min; } + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR result_type max() { return _Max; } + + static _LIBCPP_CONSTEXPR const unsigned long long _Rp = _Max - _Min + 1ull; + + // constructors and seeding functions + _LIBCPP_INLINE_VISIBILITY + shuffle_order_engine() {__init();} + _LIBCPP_INLINE_VISIBILITY + explicit shuffle_order_engine(const _Engine& __e) + : __e_(__e) {__init();} +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + explicit shuffle_order_engine(_Engine&& __e) + : __e_(_VSTD::move(__e)) {__init();} +#endif // _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + explicit shuffle_order_engine(result_type __sd) : __e_(__sd) {__init();} + template + _LIBCPP_INLINE_VISIBILITY + explicit shuffle_order_engine(_Sseq& __q, + typename enable_if<__is_seed_sequence<_Sseq, shuffle_order_engine>::value && + !is_convertible<_Sseq, _Engine>::value>::type* = 0) + : __e_(__q) {__init();} + _LIBCPP_INLINE_VISIBILITY + void seed() {__e_.seed(); __init();} + _LIBCPP_INLINE_VISIBILITY + void seed(result_type __sd) {__e_.seed(__sd); __init();} + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + __is_seed_sequence<_Sseq, shuffle_order_engine>::value, + void + >::type + seed(_Sseq& __q) {__e_.seed(__q); __init();} + + // generating functions + _LIBCPP_INLINE_VISIBILITY + result_type operator()() {return __eval(integral_constant());} + _LIBCPP_INLINE_VISIBILITY + void discard(unsigned long long __z) {for (; __z; --__z) operator()();} + + // property functions + _LIBCPP_INLINE_VISIBILITY + const _Engine& base() const _NOEXCEPT {return __e_;} + +private: + template + friend + bool + operator==( + const shuffle_order_engine<_Eng, _Kp>& __x, + const shuffle_order_engine<_Eng, _Kp>& __y); + + template + friend + bool + operator!=( + const shuffle_order_engine<_Eng, _Kp>& __x, + const shuffle_order_engine<_Eng, _Kp>& __y); + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const shuffle_order_engine<_Eng, _Kp>& __x); + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + shuffle_order_engine<_Eng, _Kp>& __x); + + _LIBCPP_INLINE_VISIBILITY + void __init() + { + for (size_t __i = 0; __i < __k; ++__i) + _V_[__i] = __e_(); + _Y_ = __e_(); + } + + _LIBCPP_INLINE_VISIBILITY + result_type __eval(false_type) {return __eval2(integral_constant());} + _LIBCPP_INLINE_VISIBILITY + result_type __eval(true_type) {return __eval(__uratio<__k, _Rp>());} + + _LIBCPP_INLINE_VISIBILITY + result_type __eval2(false_type) {return __eval(__uratio<__k/2, 0x8000000000000000ull>());} + _LIBCPP_INLINE_VISIBILITY + result_type __eval2(true_type) {return __evalf<__k, 0>();} + + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + (__uratio<_Np, _Dp>::num > 0xFFFFFFFFFFFFFFFFull / (_Max - _Min)), + result_type + >::type + __eval(__uratio<_Np, _Dp>) + {return __evalf<__uratio<_Np, _Dp>::num, __uratio<_Np, _Dp>::den>();} + + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + __uratio<_Np, _Dp>::num <= 0xFFFFFFFFFFFFFFFFull / (_Max - _Min), + result_type + >::type + __eval(__uratio<_Np, _Dp>) + { + const size_t __j = static_cast(__uratio<_Np, _Dp>::num * (_Y_ - _Min) + / __uratio<_Np, _Dp>::den); + _Y_ = _V_[__j]; + _V_[__j] = __e_(); + return _Y_; + } + + template + _LIBCPP_INLINE_VISIBILITY + result_type __evalf() + { + const double _Fp = __d == 0 ? + __n / (2. * 0x8000000000000000ull) : + __n / (double)__d; + const size_t __j = static_cast(_Fp * (_Y_ - _Min)); + _Y_ = _V_[__j]; + _V_[__j] = __e_(); + return _Y_; + } +}; + +template + _LIBCPP_CONSTEXPR const size_t shuffle_order_engine<_Engine, __k>::table_size; + +template +bool +operator==( + const shuffle_order_engine<_Eng, _Kp>& __x, + const shuffle_order_engine<_Eng, _Kp>& __y) +{ + return __x._Y_ == __y._Y_ && _VSTD::equal(__x._V_, __x._V_ + _Kp, __y._V_) && + __x.__e_ == __y.__e_; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=( + const shuffle_order_engine<_Eng, _Kp>& __x, + const shuffle_order_engine<_Eng, _Kp>& __y) +{ + return !(__x == __y); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const shuffle_order_engine<_Eng, _Kp>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _Ostream; + __os.flags(_Ostream::dec | _Ostream::left); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + __os << __x.__e_ << __sp << __x._V_[0]; + for (size_t __i = 1; __i < _Kp; ++__i) + __os << __sp << __x._V_[__i]; + return __os << __sp << __x._Y_; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + shuffle_order_engine<_Eng, _Kp>& __x) +{ + typedef typename shuffle_order_engine<_Eng, _Kp>::result_type result_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + _Eng __e; + result_type _Vp[_Kp+1]; + __is >> __e; + for (size_t __i = 0; __i < _Kp+1; ++__i) + __is >> _Vp[__i]; + if (!__is.fail()) + { + __x.__e_ = __e; + for (size_t __i = 0; __i < _Kp; ++__i) + __x._V_[__i] = _Vp[__i]; + __x._Y_ = _Vp[_Kp]; + } + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_SHUFFLE_ORDER_ENGINE_H diff --git a/contrib/llvm-project/libcxx/include/__random/student_t_distribution.h b/contrib/llvm-project/libcxx/include/__random/student_t_distribution.h new file mode 100644 index 000000000000..0cf911e4cd76 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/student_t_distribution.h @@ -0,0 +1,153 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_STUDENT_T_DISTRIBUTION_H +#define _LIBCPP___RANDOM_STUDENT_T_DISTRIBUTION_H + +#include <__config> +#include <__random/gamma_distribution.h> +#include <__random/normal_distribution.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS student_t_distribution +{ +public: + // types + typedef _RealType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + result_type __n_; + public: + typedef student_t_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(result_type __n = 1) : __n_(__n) {} + + _LIBCPP_INLINE_VISIBILITY + result_type n() const {return __n_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__n_ == __y.__n_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + normal_distribution __nd_; + +public: + // constructor and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + student_t_distribution() : student_t_distribution(1) {} + _LIBCPP_INLINE_VISIBILITY + explicit student_t_distribution(result_type __n) + : __p_(param_type(__n)) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit student_t_distribution(result_type __n = 1) + : __p_(param_type(__n)) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit student_t_distribution(const param_type& __p) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {__nd_.reset();} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + _LIBCPP_INLINE_VISIBILITY + result_type n() const {return __p_.n();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return -numeric_limits::infinity();} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return numeric_limits::infinity();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const student_t_distribution& __x, + const student_t_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const student_t_distribution& __x, + const student_t_distribution& __y) + {return !(__x == __y);} +}; + +template +template +_RealType +student_t_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) +{ + gamma_distribution __gd(__p.n() * .5, 2); + return __nd_(__g) * _VSTD::sqrt(__p.n()/__gd(__g)); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const student_t_distribution<_RT>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + __os << __x.n(); + return __os; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + student_t_distribution<_RT>& __x) +{ + typedef student_t_distribution<_RT> _Eng; + typedef typename _Eng::result_type result_type; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + result_type __n; + __is >> __n; + if (!__is.fail()) + __x.param(param_type(__n)); + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_STUDENT_T_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/subtract_with_carry_engine.h b/contrib/llvm-project/libcxx/include/__random/subtract_with_carry_engine.h new file mode 100644 index 000000000000..073f84dccff6 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/subtract_with_carry_engine.h @@ -0,0 +1,352 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_SUBTRACT_WITH_CARRY_ENGINE_H +#define _LIBCPP___RANDOM_SUBTRACT_WITH_CARRY_ENGINE_H + +#include <__algorithm/equal.h> +#include <__algorithm/min.h> +#include <__config> +#include <__random/is_seed_sequence.h> +#include <__random/linear_congruential_engine.h> +#include +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS subtract_with_carry_engine; + +template +bool +operator==( + const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x, + const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y); + +template +_LIBCPP_INLINE_VISIBILITY +bool +operator!=( + const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x, + const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y); + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x); + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x); + +template +class _LIBCPP_TEMPLATE_VIS subtract_with_carry_engine +{ +public: + // types + typedef _UIntType result_type; + +private: + result_type __x_[__r]; + result_type __c_; + size_t __i_; + + static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits::digits; + static_assert( 0 < __w, "subtract_with_carry_engine invalid parameters"); + static_assert(__w <= _Dt, "subtract_with_carry_engine invalid parameters"); + static_assert( 0 < __s, "subtract_with_carry_engine invalid parameters"); + static_assert(__s < __r, "subtract_with_carry_engine invalid parameters"); +public: + static _LIBCPP_CONSTEXPR const result_type _Min = 0; + static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) : + (result_type(1) << __w) - result_type(1); + static_assert(_Min < _Max, "subtract_with_carry_engine invalid parameters"); + + // engine characteristics + static _LIBCPP_CONSTEXPR const size_t word_size = __w; + static _LIBCPP_CONSTEXPR const size_t short_lag = __s; + static _LIBCPP_CONSTEXPR const size_t long_lag = __r; + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR result_type min() { return _Min; } + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR result_type max() { return _Max; } + static _LIBCPP_CONSTEXPR const result_type default_seed = 19780503u; + + // constructors and seeding functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + subtract_with_carry_engine() : subtract_with_carry_engine(default_seed) {} + _LIBCPP_INLINE_VISIBILITY + explicit subtract_with_carry_engine(result_type __sd) { seed(__sd); } +#else + _LIBCPP_INLINE_VISIBILITY + explicit subtract_with_carry_engine(result_type __sd = default_seed) { + seed(__sd); + } +#endif + template + _LIBCPP_INLINE_VISIBILITY + explicit subtract_with_carry_engine(_Sseq& __q, + typename enable_if<__is_seed_sequence<_Sseq, subtract_with_carry_engine>::value>::type* = 0) + {seed(__q);} + _LIBCPP_INLINE_VISIBILITY + void seed(result_type __sd = default_seed) + {seed(__sd, integral_constant());} + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + __is_seed_sequence<_Sseq, subtract_with_carry_engine>::value, + void + >::type + seed(_Sseq& __q) + {__seed(__q, integral_constant());} + + // generating functions + result_type operator()(); + _LIBCPP_INLINE_VISIBILITY + void discard(unsigned long long __z) {for (; __z; --__z) operator()();} + + template + friend + bool + operator==( + const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x, + const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y); + + template + friend + bool + operator!=( + const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x, + const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y); + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x); + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x); + +private: + + void seed(result_type __sd, integral_constant); + void seed(result_type __sd, integral_constant); + template + void __seed(_Sseq& __q, integral_constant); + template + void __seed(_Sseq& __q, integral_constant); +}; + +template + _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::word_size; + +template + _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::short_lag; + +template + _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::long_lag; + +template + _LIBCPP_CONSTEXPR const typename subtract_with_carry_engine<_UIntType, __w, __s, __r>::result_type + subtract_with_carry_engine<_UIntType, __w, __s, __r>::default_seed; + +template +void +subtract_with_carry_engine<_UIntType, __w, __s, __r>::seed(result_type __sd, + integral_constant) +{ + linear_congruential_engine + __e(__sd == 0u ? default_seed : __sd); + for (size_t __i = 0; __i < __r; ++__i) + __x_[__i] = static_cast(__e() & _Max); + __c_ = __x_[__r-1] == 0; + __i_ = 0; +} + +template +void +subtract_with_carry_engine<_UIntType, __w, __s, __r>::seed(result_type __sd, + integral_constant) +{ + linear_congruential_engine + __e(__sd == 0u ? default_seed : __sd); + for (size_t __i = 0; __i < __r; ++__i) + { + result_type __e0 = __e(); + __x_[__i] = static_cast( + (__e0 + ((uint64_t)__e() << 32)) & _Max); + } + __c_ = __x_[__r-1] == 0; + __i_ = 0; +} + +template +template +void +subtract_with_carry_engine<_UIntType, __w, __s, __r>::__seed(_Sseq& __q, + integral_constant) +{ + const unsigned __k = 1; + uint32_t __ar[__r * __k]; + __q.generate(__ar, __ar + __r * __k); + for (size_t __i = 0; __i < __r; ++__i) + __x_[__i] = static_cast(__ar[__i] & _Max); + __c_ = __x_[__r-1] == 0; + __i_ = 0; +} + +template +template +void +subtract_with_carry_engine<_UIntType, __w, __s, __r>::__seed(_Sseq& __q, + integral_constant) +{ + const unsigned __k = 2; + uint32_t __ar[__r * __k]; + __q.generate(__ar, __ar + __r * __k); + for (size_t __i = 0; __i < __r; ++__i) + __x_[__i] = static_cast( + (__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max); + __c_ = __x_[__r-1] == 0; + __i_ = 0; +} + +template +_UIntType +subtract_with_carry_engine<_UIntType, __w, __s, __r>::operator()() +{ + const result_type& __xs = __x_[(__i_ + (__r - __s)) % __r]; + result_type& __xr = __x_[__i_]; + result_type __new_c = __c_ == 0 ? __xs < __xr : __xs != 0 ? __xs <= __xr : 1; + __xr = (__xs - __xr - __c_) & _Max; + __c_ = __new_c; + __i_ = (__i_ + 1) % __r; + return __xr; +} + +template +bool +operator==( + const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x, + const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y) +{ + if (__x.__c_ != __y.__c_) + return false; + if (__x.__i_ == __y.__i_) + return _VSTD::equal(__x.__x_, __x.__x_ + _Rp, __y.__x_); + if (__x.__i_ == 0 || __y.__i_ == 0) + { + size_t __j = _VSTD::min(_Rp - __x.__i_, _Rp - __y.__i_); + if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + __x.__i_ + __j, + __y.__x_ + __y.__i_)) + return false; + if (__x.__i_ == 0) + return _VSTD::equal(__x.__x_ + __j, __x.__x_ + _Rp, __y.__x_); + return _VSTD::equal(__x.__x_, __x.__x_ + (_Rp - __j), __y.__x_ + __j); + } + if (__x.__i_ < __y.__i_) + { + size_t __j = _Rp - __y.__i_; + if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + (__x.__i_ + __j), + __y.__x_ + __y.__i_)) + return false; + if (!_VSTD::equal(__x.__x_ + (__x.__i_ + __j), __x.__x_ + _Rp, + __y.__x_)) + return false; + return _VSTD::equal(__x.__x_, __x.__x_ + __x.__i_, + __y.__x_ + (_Rp - (__x.__i_ + __j))); + } + size_t __j = _Rp - __x.__i_; + if (!_VSTD::equal(__y.__x_ + __y.__i_, __y.__x_ + (__y.__i_ + __j), + __x.__x_ + __x.__i_)) + return false; + if (!_VSTD::equal(__y.__x_ + (__y.__i_ + __j), __y.__x_ + _Rp, + __x.__x_)) + return false; + return _VSTD::equal(__y.__x_, __y.__x_ + __y.__i_, + __x.__x_ + (_Rp - (__y.__i_ + __j))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=( + const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x, + const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y) +{ + return !(__x == __y); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _Ostream; + __os.flags(_Ostream::dec | _Ostream::left); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + __os << __x.__x_[__x.__i_]; + for (size_t __j = __x.__i_ + 1; __j < _Rp; ++__j) + __os << __sp << __x.__x_[__j]; + for (size_t __j = 0; __j < __x.__i_; ++__j) + __os << __sp << __x.__x_[__j]; + __os << __sp << __x.__c_; + return __os; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + _UInt __t[_Rp+1]; + for (size_t __i = 0; __i < _Rp+1; ++__i) + __is >> __t[__i]; + if (!__is.fail()) + { + for (size_t __i = 0; __i < _Rp; ++__i) + __x.__x_[__i] = __t[__i]; + __x.__c_ = __t[_Rp]; + __x.__i_ = 0; + } + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_SUBTRACT_WITH_CARRY_ENGINE_H diff --git a/contrib/llvm-project/libcxx/include/__random/uniform_int_distribution.h b/contrib/llvm-project/libcxx/include/__random/uniform_int_distribution.h index a7cfa1ec7305..55b4761637f0 100644 --- a/contrib/llvm-project/libcxx/include/__random/uniform_int_distribution.h +++ b/contrib/llvm-project/libcxx/include/__random/uniform_int_distribution.h @@ -11,6 +11,8 @@ #include <__bits> #include <__config> +#include <__random/log2.h> +#include #include #include #include @@ -26,34 +28,6 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -// __independent_bits_engine - -template -struct __log2_imp -{ - static const size_t value = _Xp & ((unsigned long long)(1) << _Rp) ? _Rp - : __log2_imp<_Xp, _Rp - 1>::value; -}; - -template -struct __log2_imp<_Xp, 0> -{ - static const size_t value = 0; -}; - -template -struct __log2_imp<0, _Rp> -{ - static const size_t value = _Rp + 1; -}; - -template -struct __log2 -{ - static const size_t value = __log2_imp<_Xp, - sizeof(_UIntType) * __CHAR_BIT__ - 1>::value; -}; - template class __independent_bits_engine { @@ -181,7 +155,7 @@ __independent_bits_engine<_Engine, _UIntType>::__eval(true_type) return _Sp; } -template +template // __int128_t is also supported as an extension here class uniform_int_distribution { public: @@ -256,8 +230,8 @@ typename uniform_int_distribution<_IntType>::result_type uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { - typedef typename conditional::type _UIntType; + typedef typename conditional::type>::type _UIntType; const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1); if (_Rp == 1) return __p.a(); @@ -265,7 +239,7 @@ _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK typedef __independent_bits_engine<_URNG, _UIntType> _Eng; if (_Rp == 0) return static_cast(_Eng(__g, _Dt)()); - size_t __w = _Dt - __libcpp_clz(_Rp) - 1; + size_t __w = _Dt - __countl_zero(_Rp) - 1; if ((_Rp & (numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0) ++__w; _Eng __e(__g, __w); diff --git a/contrib/llvm-project/libcxx/include/__random/uniform_random_bit_generator.h b/contrib/llvm-project/libcxx/include/__random/uniform_random_bit_generator.h new file mode 100644 index 000000000000..7b2f0df868d7 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/uniform_random_bit_generator.h @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___RANDOM_UNIFORM_RANDOM_BIT_GENERATOR_H +#define _LIBCPP___RANDOM_UNIFORM_RANDOM_BIT_GENERATOR_H + +#include <__concepts/arithmetic.h> +#include <__concepts/invocable.h> +#include <__concepts/same_as.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [rand.req.urng] +template +concept uniform_random_bit_generator = + invocable<_Gen&> && unsigned_integral> && + requires { + { _Gen::min() } -> same_as>; + { _Gen::max() } -> same_as>; + requires bool_constant<(_Gen::min() < _Gen::max())>::value; + }; + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_UNIFORM_RANDOM_BIT_GENERATOR_H diff --git a/contrib/llvm-project/libcxx/include/__random/uniform_real_distribution.h b/contrib/llvm-project/libcxx/include/__random/uniform_real_distribution.h new file mode 100644 index 000000000000..967e4e26fd0c --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/uniform_real_distribution.h @@ -0,0 +1,160 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_UNIFORM_REAL_DISTRIBUTION_H +#define _LIBCPP___RANDOM_UNIFORM_REAL_DISTRIBUTION_H + +#include <__config> +#include <__random/generate_canonical.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS uniform_real_distribution +{ +public: + // types + typedef _RealType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + result_type __a_; + result_type __b_; + public: + typedef uniform_real_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(result_type __a = 0, + result_type __b = 1) + : __a_(__a), __b_(__b) {} + + _LIBCPP_INLINE_VISIBILITY + result_type a() const {return __a_;} + _LIBCPP_INLINE_VISIBILITY + result_type b() const {return __b_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + +public: + // constructors and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + uniform_real_distribution() : uniform_real_distribution(0) {} + explicit uniform_real_distribution(result_type __a, result_type __b = 1) + : __p_(param_type(__a, __b)) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit uniform_real_distribution(result_type __a = 0, result_type __b = 1) + : __p_(param_type(__a, __b)) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit uniform_real_distribution(const param_type& __p) : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template _LIBCPP_INLINE_VISIBILITY result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + _LIBCPP_INLINE_VISIBILITY + result_type a() const {return __p_.a();} + _LIBCPP_INLINE_VISIBILITY + result_type b() const {return __p_.b();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return a();} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return b();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const uniform_real_distribution& __x, + const uniform_real_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const uniform_real_distribution& __x, + const uniform_real_distribution& __y) + {return !(__x == __y);} +}; + +template +template +inline +typename uniform_real_distribution<_RealType>::result_type +uniform_real_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) +{ + return (__p.b() - __p.a()) + * _VSTD::generate_canonical<_RealType, numeric_limits<_RealType>::digits>(__g) + + __p.a(); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const uniform_real_distribution<_RT>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + return __os << __x.a() << __sp << __x.b(); +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + uniform_real_distribution<_RT>& __x) +{ + typedef uniform_real_distribution<_RT> _Eng; + typedef typename _Eng::result_type result_type; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + result_type __a; + result_type __b; + __is >> __a >> __b; + if (!__is.fail()) + __x.param(param_type(__a, __b)); + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_UNIFORM_REAL_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__random/weibull_distribution.h b/contrib/llvm-project/libcxx/include/__random/weibull_distribution.h new file mode 100644 index 000000000000..4c5e4e8fff1c --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__random/weibull_distribution.h @@ -0,0 +1,155 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_WEIBULL_DISTRIBUTION_H +#define _LIBCPP___RANDOM_WEIBULL_DISTRIBUTION_H + +#include <__config> +#include <__random/exponential_distribution.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS weibull_distribution +{ +public: + // types + typedef _RealType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + result_type __a_; + result_type __b_; + public: + typedef weibull_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(result_type __a = 1, result_type __b = 1) + : __a_(__a), __b_(__b) {} + + _LIBCPP_INLINE_VISIBILITY + result_type a() const {return __a_;} + _LIBCPP_INLINE_VISIBILITY + result_type b() const {return __b_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + +public: + // constructor and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + weibull_distribution() : weibull_distribution(1) {} + _LIBCPP_INLINE_VISIBILITY + explicit weibull_distribution(result_type __a, result_type __b = 1) + : __p_(param_type(__a, __b)) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit weibull_distribution(result_type __a = 1, result_type __b = 1) + : __p_(param_type(__a, __b)) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit weibull_distribution(const param_type& __p) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {} + + // generating functions + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g, const param_type& __p) + {return __p.b() * + _VSTD::pow(exponential_distribution()(__g), 1/__p.a());} + + // property functions + _LIBCPP_INLINE_VISIBILITY + result_type a() const {return __p_.a();} + _LIBCPP_INLINE_VISIBILITY + result_type b() const {return __p_.b();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return __p_;} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) {__p_ = __p;} + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return 0;} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return numeric_limits::infinity();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const weibull_distribution& __x, + const weibull_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const weibull_distribution& __x, + const weibull_distribution& __y) + {return !(__x == __y);} +}; + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const weibull_distribution<_RT>& __x) +{ + __save_flags<_CharT, _Traits> __lx(__os); + typedef basic_ostream<_CharT, _Traits> _OStream; + __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | + _OStream::scientific); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + __os << __x.a() << __sp << __x.b(); + return __os; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + weibull_distribution<_RT>& __x) +{ + typedef weibull_distribution<_RT> _Eng; + typedef typename _Eng::result_type result_type; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> __lx(__is); + typedef basic_istream<_CharT, _Traits> _Istream; + __is.flags(_Istream::dec | _Istream::skipws); + result_type __a; + result_type __b; + __is >> __a >> __b; + if (!__is.fail()) + __x.param(param_type(__a, __b)); + return __is; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANDOM_WEIBULL_DISTRIBUTION_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/concepts.h b/contrib/llvm-project/libcxx/include/__ranges/concepts.h index dc1cece33b8d..6a8364006beb 100644 --- a/contrib/llvm-project/libcxx/include/__ranges/concepts.h +++ b/contrib/llvm-project/libcxx/include/__ranges/concepts.h @@ -16,8 +16,8 @@ #include <__iterator/iterator_traits.h> #include <__iterator/readable_traits.h> #include <__ranges/access.h> -#include <__ranges/enable_borrowed_range.h> #include <__ranges/data.h> +#include <__ranges/enable_borrowed_range.h> #include <__ranges/enable_view.h> #include <__ranges/size.h> #include diff --git a/contrib/llvm-project/libcxx/include/__utility/priority_tag.h b/contrib/llvm-project/libcxx/include/__utility/priority_tag.h new file mode 100644 index 000000000000..45d9e5ec4c8f --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__utility/priority_tag.h @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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___UTILITY_PRIORITY_TAG_H +#define _LIBCPP___UTILITY_PRIORITY_TAG_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template struct __priority_tag : __priority_tag<_Ip - 1> {}; +template<> struct __priority_tag<0> {}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___UTILITY_PRIORITY_TAG_H diff --git a/contrib/llvm-project/libcxx/include/bit b/contrib/llvm-project/libcxx/include/bit index 634475b99879..0aab83e7a6eb 100644 --- a/contrib/llvm-project/libcxx/include/bit +++ b/contrib/llvm-project/libcxx/include/bit @@ -14,9 +14,13 @@ bit synopsis namespace std { - // [bit.cast], bit_cast - template - constexpr To bit_cast(const From& from) noexcept; // C++20 + // [bit.cast], bit_cast + template + constexpr To bit_cast(const From& from) noexcept; // C++20 + + // [bit.byteswap], byteswap + template + constexpr T byteswap(T value) noexcept; // C++23 // [bit.pow.two], integral powers of 2 template @@ -51,13 +55,14 @@ namespace std { little = see below, // C++20 big = see below, // C++20 native = see below // C++20 -}; + }; } // namespace std */ #include <__bit/bit_cast.h> +#include <__bit/byteswap.h> #include <__bits> // __libcpp_clz #include <__config> #include <__debug> diff --git a/contrib/llvm-project/libcxx/include/compare b/contrib/llvm-project/libcxx/include/compare index 8a2a82907062..5c4578da0b89 100644 --- a/contrib/llvm-project/libcxx/include/compare +++ b/contrib/llvm-project/libcxx/include/compare @@ -140,25 +140,10 @@ namespace std { #include <__compare/compare_three_way_result.h> #include <__compare/is_eq.h> #include <__compare/ordering.h> +#include <__compare/partial_order.h> +#include <__compare/strong_order.h> #include <__compare/three_way_comparable.h> +#include <__compare/weak_order.h> #include <__config> -#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -#pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if _LIBCPP_STD_VER > 17 - -// [cmp.alg], comparison algorithms -// TODO: unimplemented -template constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs); -template constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs); -template constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs); - -#endif // _LIBCPP_STD_VER > 17 - -_LIBCPP_END_NAMESPACE_STD - #endif // _LIBCPP_COMPARE diff --git a/contrib/llvm-project/libcxx/include/deque b/contrib/llvm-project/libcxx/include/deque index 9ab6ea748d53..e45d780e274f 100644 --- a/contrib/llvm-project/libcxx/include/deque +++ b/contrib/llvm-project/libcxx/include/deque @@ -915,16 +915,16 @@ class __deque_base __deque_base(const __deque_base& __c); __deque_base& operator=(const __deque_base& __c); public: - typedef _Allocator allocator_type; - typedef allocator_traits __alloc_traits; - typedef typename __alloc_traits::size_type size_type; + typedef _Allocator allocator_type; + typedef allocator_traits __alloc_traits; + typedef typename __alloc_traits::size_type size_type; - typedef _Tp value_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename __alloc_traits::difference_type difference_type; - typedef typename __alloc_traits::pointer pointer; - typedef typename __alloc_traits::const_pointer const_pointer; + typedef _Tp value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename __alloc_traits::difference_type difference_type; + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; static const difference_type __block_size; @@ -1259,20 +1259,20 @@ public: static_assert((is_same::value), "Allocator::value_type must be same type as value_type"); - typedef __deque_base __base; + typedef __deque_base __base; - typedef typename __base::__alloc_traits __alloc_traits; - typedef typename __base::reference reference; - typedef typename __base::const_reference const_reference; - typedef typename __base::iterator iterator; - typedef typename __base::const_iterator const_iterator; - typedef typename __allocator_traits::size_type size_type; - typedef typename __base::difference_type difference_type; + typedef typename __base::__alloc_traits __alloc_traits; + typedef typename __base::reference reference; + typedef typename __base::const_reference const_reference; + typedef typename __base::iterator iterator; + typedef typename __base::const_iterator const_iterator; + typedef typename __base::size_type size_type; + typedef typename __base::difference_type difference_type; - typedef typename __base::pointer pointer; - typedef typename __base::const_pointer const_pointer; - typedef _VSTD::reverse_iterator reverse_iterator; - typedef _VSTD::reverse_iterator const_reverse_iterator; + typedef typename __base::pointer pointer; + typedef typename __base::const_pointer const_pointer; + typedef _VSTD::reverse_iterator reverse_iterator; + typedef _VSTD::reverse_iterator const_reverse_iterator; using typename __base::__deque_range; using typename __base::__deque_block_range; @@ -1289,7 +1289,14 @@ public: explicit deque(size_type __n, const _Allocator& __a); #endif deque(size_type __n, const value_type& __v); - deque(size_type __n, const value_type& __v, const allocator_type& __a); + + template ::value> > + deque(size_type __n, const value_type& __v, const allocator_type& __a) : __base(__a) + { + if (__n > 0) + __append(__n, __v); + } + template deque(_InputIter __f, _InputIter __l, typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0); @@ -1608,14 +1615,6 @@ deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v) __append(__n, __v); } -template -deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v, const allocator_type& __a) - : __base(__a) -{ - if (__n > 0) - __append(__n, __v); -} - template template deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, diff --git a/contrib/llvm-project/libcxx/include/filesystem b/contrib/llvm-project/libcxx/include/filesystem index dcbdbbae6985..39e8ca2e814b 100644 --- a/contrib/llvm-project/libcxx/include/filesystem +++ b/contrib/llvm-project/libcxx/include/filesystem @@ -1033,7 +1033,7 @@ public: auto __p_root_name = __p.__root_name(); auto __p_root_name_size = __p_root_name.size(); if (__p.is_absolute() || - (!__p_root_name.empty() && __p_root_name != root_name())) { + (!__p_root_name.empty() && __p_root_name != __string_view(root_name().__pn_))) { __pn_ = __p.__pn_; return *this; } @@ -1492,22 +1492,22 @@ public: #endif // !_LIBCPP_HAS_NO_LOCALIZATION friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept { - return __lhs.compare(__rhs) == 0; + return __lhs.__compare(__rhs.__pn_) == 0; } friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept { - return __lhs.compare(__rhs) != 0; + return __lhs.__compare(__rhs.__pn_) != 0; } friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept { - return __lhs.compare(__rhs) < 0; + return __lhs.__compare(__rhs.__pn_) < 0; } friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept { - return __lhs.compare(__rhs) <= 0; + return __lhs.__compare(__rhs.__pn_) <= 0; } friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept { - return __lhs.compare(__rhs) > 0; + return __lhs.__compare(__rhs.__pn_) > 0; } friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept { - return __lhs.compare(__rhs) >= 0; + return __lhs.__compare(__rhs.__pn_) >= 0; } friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs, @@ -3024,13 +3024,17 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM #if !defined(_LIBCPP_HAS_NO_RANGES) template <> +_LIBCPP_AVAILABILITY_FILESYSTEM inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::directory_iterator> = true; template <> +_LIBCPP_AVAILABILITY_FILESYSTEM inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::recursive_directory_iterator> = true; template <> +_LIBCPP_AVAILABILITY_FILESYSTEM inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::directory_iterator> = true; template <> +_LIBCPP_AVAILABILITY_FILESYSTEM inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::recursive_directory_iterator> = true; #endif diff --git a/contrib/llvm-project/libcxx/include/format b/contrib/llvm-project/libcxx/include/format index e1d47c9f84dd..788b9c299abc 100644 --- a/contrib/llvm-project/libcxx/include/format +++ b/contrib/llvm-project/libcxx/include/format @@ -51,9 +51,6 @@ namespace std { using wformat_args = basic_format_args; - template - using format_args_t = basic_format_args>; - // [format.functions], formatting functions template string format(string_view fmt, const Args&... args); @@ -79,17 +76,15 @@ namespace std { Out format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args); template - Out vformat_to(Out out, string_view fmt, - format_args_t, char> args); + Out vformat_to(Out out, string_view fmt, format_args args); template - Out vformat_to(Out out, wstring_view fmt, - format_args_t, wchar_t> args); + Out vformat_to(Out out, wstring_view fmt, wformat_args args); template Out vformat_to(Out out, const locale& loc, string_view fmt, - format_args_t, char> args); + format_args char> args); template Out vformat_to(Out out, const locale& loc, wstring_view fmt, - format_args_t, wchar_t> args); + wformat_args args); template struct format_to_n_result { Out out; @@ -325,9 +320,6 @@ using format_args = basic_format_args; using wformat_args = basic_format_args; #endif -template -using format_args_t = basic_format_args>; - template struct _LIBCPP_TEMPLATE_VIS __format_arg_store { // TODO FMT Use a built-in array. @@ -436,51 +428,55 @@ __vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) { } // namespace __format -template +template requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt - __vformat_to(_OutIt __out_it, basic_string_view<_CharT> __fmt, - format_args_t, _CharT> __args) { - return __format::__vformat_to( - basic_format_parse_context{__fmt, __args.__size()}, - _VSTD::__format_context_create(_VSTD::move(__out_it), __args)); + __vformat_to( + _OutIt __out_it, basic_string_view<_CharT> __fmt, + basic_format_args> __args) { + if constexpr (same_as<_OutIt, _FormatOutIt>) + return _VSTD::__format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(_VSTD::move(__out_it), __args)); + else { + basic_string<_CharT> __str; + _VSTD::__format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(_VSTD::back_inserter(__str), __args)); + return _VSTD::copy_n(__str.begin(), __str.size(), _VSTD::move(__out_it)); + } } template _OutIt> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt -vformat_to(_OutIt __out_it, string_view __fmt, - format_args_t, char> __args) { +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) { return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); } #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt -vformat_to(_OutIt __out_it, wstring_view __fmt, - format_args_t, wchar_t> __args) { +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) { return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); } #endif template _OutIt, class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to(_OutIt __out_it, string_view __fmt, const _Args&... __args) { - return _VSTD::vformat_to( - _VSTD::move(__out_it), __fmt, - _VSTD::make_format_args>(__args...)); + return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt, + _VSTD::make_format_args(__args...)); } #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt, class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to(_OutIt __out_it, wstring_view __fmt, const _Args&... __args) { - return _VSTD::vformat_to( - _VSTD::move(__out_it), __fmt, - _VSTD::make_format_args>( - __args...)); + return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt, + _VSTD::make_wformat_args(__args...)); } #endif -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string +_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string vformat(string_view __fmt, format_args __args) { string __res; _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); @@ -488,7 +484,7 @@ vformat(string_view __fmt, format_args __args) { } #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring vformat(wstring_view __fmt, wformat_args __args) { wstring __res; _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); @@ -497,14 +493,14 @@ vformat(wstring_view __fmt, wformat_args __args) { #endif template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(string_view __fmt, const _Args&... __args) { return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)); } #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring format(wstring_view __fmt, const _Args&... __args) { return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)); } @@ -556,54 +552,59 @@ formatted_size(wstring_view __fmt, const _Args&... __args) { #ifndef _LIBCPP_HAS_NO_LOCALIZATION -template +template requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt - __vformat_to(_OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt, - format_args_t, _CharT> __args) { - return __format::__vformat_to( - basic_format_parse_context{__fmt, __args.__size()}, - _VSTD::__format_context_create(_VSTD::move(__out_it), __args, - _VSTD::move(__loc))); + __vformat_to( + _OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt, + basic_format_args> __args) { + if constexpr (same_as<_OutIt, _FormatOutIt>) + return _VSTD::__format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(_VSTD::move(__out_it), __args, + _VSTD::move(__loc))); + else { + basic_string<_CharT> __str; + _VSTD::__format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(_VSTD::back_inserter(__str), __args, + _VSTD::move(__loc))); + return _VSTD::copy_n(__str.begin(), __str.size(), _VSTD::move(__out_it)); + } } template _OutIt> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt -vformat_to(_OutIt __out_it, locale __loc, string_view __fmt, - format_args_t, char> __args) { +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to( + _OutIt __out_it, locale __loc, string_view __fmt, format_args __args) { return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, __args); } #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt -vformat_to(_OutIt __out_it, locale __loc, wstring_view __fmt, - format_args_t, wchar_t> __args) { +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to( + _OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) { return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, __args); } #endif template _OutIt, class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( _OutIt __out_it, locale __loc, string_view __fmt, const _Args&... __args) { - return _VSTD::vformat_to( - _VSTD::move(__out_it), _VSTD::move(__loc), __fmt, - _VSTD::make_format_args>(__args...)); + return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, + _VSTD::make_format_args(__args...)); } #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt, class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( _OutIt __out_it, locale __loc, wstring_view __fmt, const _Args&... __args) { - return _VSTD::vformat_to( - _VSTD::move(__out_it), _VSTD::move(__loc), __fmt, - _VSTD::make_format_args>( - __args...)); + return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, + _VSTD::make_wformat_args(__args...)); } #endif -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string +_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string vformat(locale __loc, string_view __fmt, format_args __args) { string __res; _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, @@ -612,7 +613,7 @@ vformat(locale __loc, string_view __fmt, format_args __args) { } #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring vformat(locale __loc, wstring_view __fmt, wformat_args __args) { wstring __res; _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, @@ -622,7 +623,7 @@ vformat(locale __loc, wstring_view __fmt, wformat_args __args) { #endif template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(locale __loc, string_view __fmt, const _Args&... __args) { return _VSTD::vformat(_VSTD::move(__loc), __fmt, _VSTD::make_format_args(__args...)); @@ -630,7 +631,7 @@ format(locale __loc, string_view __fmt, const _Args&... __args) { #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring format(locale __loc, wstring_view __fmt, const _Args&... __args) { return _VSTD::vformat(_VSTD::move(__loc), __fmt, _VSTD::make_wformat_args(__args...)); diff --git a/contrib/llvm-project/libcxx/include/forward_list b/contrib/llvm-project/libcxx/include/forward_list index 9d19e741f061..34168e88746e 100644 --- a/contrib/llvm-project/libcxx/include/forward_list +++ b/contrib/llvm-project/libcxx/include/forward_list @@ -186,6 +186,7 @@ template #include #include #include +#include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -643,12 +644,12 @@ public: static_assert((is_same::value), "Allocator::value_type must be same type as value_type"); - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef typename __allocator_traits::size_type size_type; - typedef typename allocator_traits::difference_type difference_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename allocator_traits::pointer pointer; + typedef typename allocator_traits::const_pointer const_pointer; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::difference_type difference_type; typedef typename base::iterator iterator; typedef typename base::const_iterator const_iterator; @@ -669,7 +670,13 @@ public: explicit forward_list(size_type __n, const allocator_type& __a); #endif forward_list(size_type __n, const value_type& __v); - forward_list(size_type __n, const value_type& __v, const allocator_type& __a); + + template ::value> > + forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : base(__a) + { + insert_after(cbefore_begin(), __n, __v); + } + template forward_list(_InputIterator __f, _InputIterator __l, typename enable_if< @@ -943,14 +950,6 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v) insert_after(cbefore_begin(), __n, __v); } -template -forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v, - const allocator_type& __a) - : base(__a) -{ - insert_after(cbefore_begin(), __n, __v); -} - template template forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, diff --git a/contrib/llvm-project/libcxx/include/list b/contrib/llvm-project/libcxx/include/list index 6282983ad20a..c9c050a4f1f0 100644 --- a/contrib/llvm-project/libcxx/include/list +++ b/contrib/llvm-project/libcxx/include/list @@ -845,24 +845,24 @@ class _LIBCPP_TEMPLATE_VIS list typedef typename base::__link_pointer __link_pointer; public: - typedef _Tp value_type; - typedef _Alloc allocator_type; + typedef _Tp value_type; + typedef _Alloc allocator_type; static_assert((is_same::value), "Invalid allocator::value_type"); - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename base::pointer pointer; - typedef typename base::const_pointer const_pointer; - typedef typename __allocator_traits::size_type size_type; - typedef typename base::difference_type difference_type; - typedef typename base::iterator iterator; - typedef typename base::const_iterator const_iterator; - typedef _VSTD::reverse_iterator reverse_iterator; - typedef _VSTD::reverse_iterator const_reverse_iterator; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename base::pointer pointer; + typedef typename base::const_pointer const_pointer; + typedef typename base::size_type size_type; + typedef typename base::difference_type difference_type; + typedef typename base::iterator iterator; + typedef typename base::const_iterator const_iterator; + typedef _VSTD::reverse_iterator reverse_iterator; + typedef _VSTD::reverse_iterator const_reverse_iterator; #if _LIBCPP_STD_VER > 17 - typedef size_type __remove_return_type; + typedef size_type __remove_return_type; #else - typedef void __remove_return_type; + typedef void __remove_return_type; #endif _LIBCPP_INLINE_VISIBILITY @@ -885,7 +885,16 @@ public: explicit list(size_type __n, const allocator_type& __a); #endif list(size_type __n, const value_type& __x); - list(size_type __n, const value_type& __x, const allocator_type& __a); + template ::value> > + list(size_type __n, const value_type& __x, const allocator_type& __a) : base(__a) + { +#if _LIBCPP_DEBUG_LEVEL == 2 + __get_db()->__insert_c(this); +#endif + for (; __n > 0; --__n) + push_back(__x); + } + template list(_InpIter __f, _InpIter __l, typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0); @@ -1241,17 +1250,6 @@ list<_Tp, _Alloc>::list(size_type __n, const value_type& __x) push_back(__x); } -template -list<_Tp, _Alloc>::list(size_type __n, const value_type& __x, const allocator_type& __a) - : base(__a) -{ -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif - for (; __n > 0; --__n) - push_back(__x); -} - template template list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, diff --git a/contrib/llvm-project/libcxx/include/module.modulemap b/contrib/llvm-project/libcxx/include/module.modulemap index f34442ed5c9a..a4a264bd9147 100644 --- a/contrib/llvm-project/libcxx/include/module.modulemap +++ b/contrib/llvm-project/libcxx/include/module.modulemap @@ -338,6 +338,7 @@ module std [system] { module __bit { module bit_cast { private header "__bit/bit_cast.h" } + module byteswap { private header "__bit/byteswap.h" } } } module bitset { @@ -376,8 +377,11 @@ module std [system] { module compare_three_way_result { private header "__compare/compare_three_way_result.h" } module is_eq { private header "__compare/is_eq.h" } module ordering { private header "__compare/ordering.h" } + module partial_order { private header "__compare/partial_order.h" } + module strong_order { private header "__compare/strong_order.h" } module synth_three_way { private header "__compare/synth_three_way.h" } module three_way_comparable { private header "__compare/three_way_comparable.h" } + module weak_order { private header "__compare/weak_order.h" } } } module complex { @@ -658,6 +662,22 @@ module std [system] { module numeric { header "numeric" export * + + module __numeric { + module accumulate { private header "__numeric/accumulate.h" } + module adjacent_difference { private header "__numeric/adjacent_difference.h" } + module exclusive_scan { private header "__numeric/exclusive_scan.h" } + module gcd_lcm { private header "__numeric/gcd_lcm.h" } + module inclusive_scan { private header "__numeric/inclusive_scan.h" } + module inner_product { private header "__numeric/inner_product.h" } + module iota { private header "__numeric/iota.h" } + module midpoint { private header "__numeric/midpoint.h" } + module partial_sum { private header "__numeric/partial_sum.h" } + module reduce { private header "__numeric/reduce.h" } + module transform_exclusive_scan { private header "__numeric/transform_exclusive_scan.h" } + module transform_inclusive_scan { private header "__numeric/transform_inclusive_scan.h" } + module transform_reduce { private header "__numeric/transform_reduce.h" } + } } module optional { header "optional" @@ -679,7 +699,41 @@ module std [system] { export * module __random { - module uniform_int_distribution { private header "__random/uniform_int_distribution.h" } + module bernoulli_distribution { private header "__random/bernoulli_distribution.h" } + module binomial_distribution { private header "__random/binomial_distribution.h" } + module cauchy_distribution { private header "__random/cauchy_distribution.h" } + module chi_squared_distribution { private header "__random/chi_squared_distribution.h" } + module default_random_engine { private header "__random/default_random_engine.h" } + module discard_block_engine { private header "__random/discard_block_engine.h" } + module discrete_distribution { private header "__random/discrete_distribution.h" } + module exponential_distribution { private header "__random/exponential_distribution.h" } + module extreme_value_distribution { private header "__random/extreme_value_distribution.h" } + module fisher_f_distribution { private header "__random/fisher_f_distribution.h" } + module gamma_distribution { private header "__random/gamma_distribution.h" } + module generate_canonical { private header "__random/generate_canonical.h" } + module geometric_distribution { private header "__random/geometric_distribution.h" } + module independent_bits_engine { private header "__random/independent_bits_engine.h" } + module is_seed_sequence { private header "__random/is_seed_sequence.h" } + module knuth_b { private header "__random/knuth_b.h" } + module linear_congruential_engine { private header "__random/linear_congruential_engine.h" } + module log2 { private header "__random/log2.h" } + module lognormal_distribution { private header "__random/lognormal_distribution.h" } + module mersenne_twister_engine { private header "__random/mersenne_twister_engine.h" } + module negative_binomial_distribution { private header "__random/negative_binomial_distribution.h" } + module normal_distribution { private header "__random/normal_distribution.h" } + module piecewise_constant_distribution { private header "__random/piecewise_constant_distribution.h" } + module piecewise_linear_distribution { private header "__random/piecewise_linear_distribution.h" } + module poisson_distribution { private header "__random/poisson_distribution.h" } + module random_device { private header "__random/random_device.h" } + module ranlux { private header "__random/ranlux.h" } + module seed_seq { private header "__random/seed_seq.h" } + module shuffle_order_engine { private header "__random/shuffle_order_engine.h" } + module student_t_distribution { private header "__random/student_t_distribution.h" } + module subtract_with_carry_engine { private header "__random/subtract_with_carry_engine.h" } + module uniform_int_distribution { private header "__random/uniform_int_distribution.h" } + module uniform_random_bit_generator { private header "__random/uniform_random_bit_generator.h" } + module uniform_real_distribution { private header "__random/uniform_real_distribution.h" } + module weibull_distribution { private header "__random/weibull_distribution.h" } } } module ranges { @@ -848,6 +902,7 @@ module std [system] { module move { private header "__utility/move.h" } module pair { private header "__utility/pair.h" } module piecewise_construct { private header "__utility/piecewise_construct.h" } + module priority_tag { private header "__utility/priority_tag.h" } module rel_ops { private header "__utility/rel_ops.h" } module swap { private header "__utility/swap.h" } module to_underlying { private header "__utility/to_underlying.h" } diff --git a/contrib/llvm-project/libcxx/include/numeric b/contrib/llvm-project/libcxx/include/numeric index fc44efff761d..09d15a6024de 100644 --- a/contrib/llvm-project/libcxx/include/numeric +++ b/contrib/llvm-project/libcxx/include/numeric @@ -145,490 +145,29 @@ template */ #include <__config> -#include <__debug> #include // for isnormal #include #include -#include // for numeric_limits #include +#include <__numeric/accumulate.h> +#include <__numeric/adjacent_difference.h> +#include <__numeric/exclusive_scan.h> +#include <__numeric/gcd_lcm.h> +#include <__numeric/inclusive_scan.h> +#include <__numeric/inner_product.h> +#include <__numeric/iota.h> +#include <__numeric/midpoint.h> +#include <__numeric/partial_sum.h> +#include <__numeric/reduce.h> +#include <__numeric/transform_exclusive_scan.h> +#include <__numeric/transform_inclusive_scan.h> +#include <__numeric/transform_reduce.h> + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - -_LIBCPP_BEGIN_NAMESPACE_STD - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_Tp -accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) -{ - for (; __first != __last; ++__first) -#if _LIBCPP_STD_VER > 17 - __init = _VSTD::move(__init) + *__first; -#else - __init = __init + *__first; -#endif - return __init; -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_Tp -accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op) -{ - for (; __first != __last; ++__first) -#if _LIBCPP_STD_VER > 17 - __init = __binary_op(_VSTD::move(__init), *__first); -#else - __init = __binary_op(__init, *__first); -#endif - return __init; -} - -#if _LIBCPP_STD_VER > 14 -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_Tp -reduce(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOp __b) -{ - for (; __first != __last; ++__first) - __init = __b(__init, *__first); - return __init; -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_Tp -reduce(_InputIterator __first, _InputIterator __last, _Tp __init) -{ - return _VSTD::reduce(__first, __last, __init, _VSTD::plus<>()); -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -typename iterator_traits<_InputIterator>::value_type -reduce(_InputIterator __first, _InputIterator __last) -{ - return _VSTD::reduce(__first, __last, - typename iterator_traits<_InputIterator>::value_type{}); -} -#endif - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_Tp -inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init) -{ - for (; __first1 != __last1; ++__first1, (void) ++__first2) -#if _LIBCPP_STD_VER > 17 - __init = _VSTD::move(__init) + *__first1 * *__first2; -#else - __init = __init + *__first1 * *__first2; -#endif - return __init; -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_Tp -inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, - _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) -{ - for (; __first1 != __last1; ++__first1, (void) ++__first2) -#if _LIBCPP_STD_VER > 17 - __init = __binary_op1(_VSTD::move(__init), __binary_op2(*__first1, *__first2)); -#else - __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); -#endif - return __init; -} - -#if _LIBCPP_STD_VER > 14 -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_Tp -transform_reduce(_InputIterator __first, _InputIterator __last, - _Tp __init, _BinaryOp __b, _UnaryOp __u) -{ - for (; __first != __last; ++__first) - __init = __b(__init, __u(*__first)); - return __init; -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_Tp -transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _Tp __init, _BinaryOp1 __b1, _BinaryOp2 __b2) -{ - for (; __first1 != __last1; ++__first1, (void) ++__first2) - __init = __b1(__init, __b2(*__first1, *__first2)); - return __init; -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_Tp -transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _Tp __init) -{ - return _VSTD::transform_reduce(__first1, __last1, __first2, _VSTD::move(__init), - _VSTD::plus<>(), _VSTD::multiplies<>()); -} -#endif - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - if (__first != __last) - { - typename iterator_traits<_InputIterator>::value_type __t(*__first); - *__result = __t; - for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) - { -#if _LIBCPP_STD_VER > 17 - __t = _VSTD::move(__t) + *__first; -#else - __t = __t + *__first; -#endif - *__result = __t; - } - } - return __result; -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result, - _BinaryOperation __binary_op) -{ - if (__first != __last) - { - typename iterator_traits<_InputIterator>::value_type __t(*__first); - *__result = __t; - for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) - { -#if _LIBCPP_STD_VER > 17 - __t = __binary_op(_VSTD::move(__t), *__first); -#else - __t = __binary_op(__t, *__first); -#endif - *__result = __t; - } - } - return __result; -} - -#if _LIBCPP_STD_VER > 14 -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -exclusive_scan(_InputIterator __first, _InputIterator __last, - _OutputIterator __result, _Tp __init, _BinaryOp __b) -{ - if (__first != __last) - { - _Tp __tmp(__b(__init, *__first)); - while (true) - { - *__result = _VSTD::move(__init); - ++__result; - ++__first; - if (__first == __last) - break; - __init = _VSTD::move(__tmp); - __tmp = __b(__init, *__first); - } - } - return __result; -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -exclusive_scan(_InputIterator __first, _InputIterator __last, - _OutputIterator __result, _Tp __init) -{ - return _VSTD::exclusive_scan(__first, __last, __result, __init, _VSTD::plus<>()); -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, - _OutputIterator __result, _BinaryOp __b, _Tp __init) -{ - for (; __first != __last; ++__first, (void) ++__result) { - __init = __b(__init, *__first); - *__result = __init; - } - return __result; -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, - _OutputIterator __result, _BinaryOp __b) -{ - if (__first != __last) { - typename iterator_traits<_InputIterator>::value_type __init = *__first; - *__result++ = __init; - if (++__first != __last) - return _VSTD::inclusive_scan(__first, __last, __result, __b, __init); - } - - return __result; -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, - _OutputIterator __result) -{ - return _VSTD::inclusive_scan(__first, __last, __result, _VSTD::plus<>()); -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -transform_exclusive_scan(_InputIterator __first, _InputIterator __last, - _OutputIterator __result, _Tp __init, - _BinaryOp __b, _UnaryOp __u) -{ - if (__first != __last) - { - _Tp __saved = __init; - do - { - __init = __b(__init, __u(*__first)); - *__result = __saved; - __saved = __init; - ++__result; - } while (++__first != __last); - } - return __result; -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -transform_inclusive_scan(_InputIterator __first, _InputIterator __last, - _OutputIterator __result, _BinaryOp __b, _UnaryOp __u, _Tp __init) -{ - for (; __first != __last; ++__first, (void) ++__result) { - __init = __b(__init, __u(*__first)); - *__result = __init; - } - - return __result; -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -transform_inclusive_scan(_InputIterator __first, _InputIterator __last, - _OutputIterator __result, _BinaryOp __b, _UnaryOp __u) -{ - if (__first != __last) { - typename iterator_traits<_InputIterator>::value_type __init = __u(*__first); - *__result++ = __init; - if (++__first != __last) - return _VSTD::transform_inclusive_scan(__first, __last, __result, __b, __u, __init); - } - - return __result; -} -#endif - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - if (__first != __last) - { - typename iterator_traits<_InputIterator>::value_type __acc(*__first); - *__result = __acc; - for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) - { - typename iterator_traits<_InputIterator>::value_type __val(*__first); -#if _LIBCPP_STD_VER > 17 - *__result = __val - _VSTD::move(__acc); -#else - *__result = __val - __acc; -#endif - __acc = _VSTD::move(__val); - } - } - return __result; -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result, - _BinaryOperation __binary_op) -{ - if (__first != __last) - { - typename iterator_traits<_InputIterator>::value_type __acc(*__first); - *__result = __acc; - for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) - { - typename iterator_traits<_InputIterator>::value_type __val(*__first); -#if _LIBCPP_STD_VER > 17 - *__result = __binary_op(__val, _VSTD::move(__acc)); -#else - *__result = __binary_op(__val, __acc); -#endif - __acc = _VSTD::move(__val); - } - } - return __result; -} - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -void -iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value_) -{ - for (; __first != __last; ++__first, (void) ++__value_) - *__first = __value_; -} - - -#if _LIBCPP_STD_VER > 14 -template ::value> struct __ct_abs; - -template -struct __ct_abs<_Result, _Source, true> { - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - _Result operator()(_Source __t) const noexcept - { - if (__t >= 0) return __t; - if (__t == numeric_limits<_Source>::min()) return -static_cast<_Result>(__t); - return -__t; - } -}; - -template -struct __ct_abs<_Result, _Source, false> { - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - _Result operator()(_Source __t) const noexcept { return __t; } -}; - - -template -_LIBCPP_CONSTEXPR _LIBCPP_HIDDEN -_Tp __gcd(_Tp __m, _Tp __n) -{ - static_assert((!is_signed<_Tp>::value), ""); - return __n == 0 ? __m : _VSTD::__gcd<_Tp>(__n, __m % __n); -} - - -template -_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY -common_type_t<_Tp,_Up> -gcd(_Tp __m, _Up __n) -{ - static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to gcd must be integer types"); - static_assert((!is_same::type, bool>::value), "First argument to gcd cannot be bool" ); - static_assert((!is_same::type, bool>::value), "Second argument to gcd cannot be bool" ); - using _Rp = common_type_t<_Tp,_Up>; - using _Wp = make_unsigned_t<_Rp>; - return static_cast<_Rp>(_VSTD::__gcd( - static_cast<_Wp>(__ct_abs<_Rp, _Tp>()(__m)), - static_cast<_Wp>(__ct_abs<_Rp, _Up>()(__n)))); -} - -template -_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY -common_type_t<_Tp,_Up> -lcm(_Tp __m, _Up __n) -{ - static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to lcm must be integer types"); - static_assert((!is_same::type, bool>::value), "First argument to lcm cannot be bool" ); - static_assert((!is_same::type, bool>::value), "Second argument to lcm cannot be bool" ); - if (__m == 0 || __n == 0) - return 0; - - using _Rp = common_type_t<_Tp,_Up>; - _Rp __val1 = __ct_abs<_Rp, _Tp>()(__m) / _VSTD::gcd(__m, __n); - _Rp __val2 = __ct_abs<_Rp, _Up>()(__n); - _LIBCPP_ASSERT((numeric_limits<_Rp>::max() / __val1 > __val2), "Overflow in lcm"); - return __val1 * __val2; -} - -#endif /* _LIBCPP_STD_VER > 14 */ - -#if _LIBCPP_STD_VER > 17 -template -_LIBCPP_INLINE_VISIBILITY constexpr -enable_if_t && !is_same_v && !is_null_pointer_v<_Tp>, _Tp> -midpoint(_Tp __a, _Tp __b) noexcept -_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK -{ - using _Up = make_unsigned_t<_Tp>; - constexpr _Up __bitshift = numeric_limits<_Up>::digits - 1; - - _Up __diff = _Up(__b) - _Up(__a); - _Up __sign_bit = __b < __a; - - _Up __half_diff = (__diff / 2) + (__sign_bit << __bitshift) + (__sign_bit & __diff); - - return __a + __half_diff; -} - - -template -_LIBCPP_INLINE_VISIBILITY constexpr -enable_if_t - && is_object_v> - && ! is_void_v> - && (sizeof(remove_pointer_t<_TPtr>) > 0), _TPtr> -midpoint(_TPtr __a, _TPtr __b) noexcept -{ - return __a + _VSTD::midpoint(ptrdiff_t(0), __b - __a); -} - - -template -constexpr int __sign(_Tp __val) { - return (_Tp(0) < __val) - (__val < _Tp(0)); -} - -template -constexpr _Fp __fp_abs(_Fp __f) { return __f >= 0 ? __f : -__f; } - -template -_LIBCPP_INLINE_VISIBILITY constexpr -enable_if_t, _Fp> -midpoint(_Fp __a, _Fp __b) noexcept -{ - constexpr _Fp __lo = numeric_limits<_Fp>::min()*2; - constexpr _Fp __hi = numeric_limits<_Fp>::max()/2; - return __fp_abs(__a) <= __hi && __fp_abs(__b) <= __hi ? // typical case: overflow is impossible - (__a + __b)/2 : // always correctly rounded - __fp_abs(__a) < __lo ? __a + __b/2 : // not safe to halve a - __fp_abs(__b) < __lo ? __a/2 + __b : // not safe to halve b - __a/2 + __b/2; // otherwise correctly rounded -} - -#endif // _LIBCPP_STD_VER > 17 - -_LIBCPP_END_NAMESPACE_STD - -_LIBCPP_POP_MACROS - #if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 # include <__pstl_numeric> #endif diff --git a/contrib/llvm-project/libcxx/include/random b/contrib/llvm-project/libcxx/include/random index 72d9855765f8..9eb70bac00b9 100644 --- a/contrib/llvm-project/libcxx/include/random +++ b/contrib/llvm-project/libcxx/include/random @@ -1678,5330 +1678,56 @@ class piecewise_linear_distribution */ #include <__config> +#include <__random/bernoulli_distribution.h> +#include <__random/binomial_distribution.h> +#include <__random/cauchy_distribution.h> +#include <__random/chi_squared_distribution.h> +#include <__random/default_random_engine.h> +#include <__random/discard_block_engine.h> +#include <__random/discrete_distribution.h> +#include <__random/exponential_distribution.h> +#include <__random/extreme_value_distribution.h> +#include <__random/fisher_f_distribution.h> +#include <__random/gamma_distribution.h> +#include <__random/generate_canonical.h> +#include <__random/geometric_distribution.h> +#include <__random/independent_bits_engine.h> +#include <__random/is_seed_sequence.h> +#include <__random/knuth_b.h> +#include <__random/linear_congruential_engine.h> +#include <__random/log2.h> +#include <__random/lognormal_distribution.h> +#include <__random/mersenne_twister_engine.h> +#include <__random/negative_binomial_distribution.h> +#include <__random/normal_distribution.h> +#include <__random/piecewise_constant_distribution.h> +#include <__random/piecewise_linear_distribution.h> +#include <__random/poisson_distribution.h> +#include <__random/random_device.h> +#include <__random/ranlux.h> +#include <__random/seed_seq.h> +#include <__random/shuffle_order_engine.h> +#include <__random/student_t_distribution.h> +#include <__random/subtract_with_carry_engine.h> #include <__random/uniform_int_distribution.h> -#include -#include -#include -#include -#include +#include <__random/uniform_random_bit_generator.h> +#include <__random/uniform_real_distribution.h> +#include <__random/weibull_distribution.h> #include -#include -#include -#include -#include -#include -#include + +#include // for backward compatibility; TODO remove it +#include // for backward compatibility; TODO remove it +#include // for backward compatibility; TODO remove it +#include // for backward compatibility; TODO remove it +#include // for backward compatibility; TODO remove it +#include // for backward compatibility; TODO remove it +#include // for backward compatibility; TODO remove it +#include // for backward compatibility; TODO remove it +#include // for backward compatibility; TODO remove it +#include // for backward compatibility; TODO remove it #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) - -// [rand.req.urng] -template -concept uniform_random_bit_generator = - invocable<_Gen&> && unsigned_integral> && - requires { - { _Gen::min() } -> same_as>; - { _Gen::max() } -> same_as>; - requires bool_constant<(_Gen::min() < _Gen::max())>::value; - }; - -#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) - -// __is_seed_sequence - -template -struct __is_seed_sequence -{ - static _LIBCPP_CONSTEXPR const bool value = - !is_convertible<_Sseq, typename _Engine::result_type>::value && - !is_same::type, _Engine>::value; -}; - -// linear_congruential_engine - -template (_Mp-__c)/__a), - bool _OverflowOK = ((__m | (__m-1)) > __m), // m = 2^n - bool _SchrageOK = (__a != 0 && __m != 0 && __m % __a <= __m / __a)> // r <= q -struct __lce_alg_picker -{ - static_assert(__a != 0 || __m != 0 || !_MightOverflow || _OverflowOK || _SchrageOK, - "The current values of a, c, and m cannot generate a number " - "within bounds of linear_congruential_engine."); - - static _LIBCPP_CONSTEXPR const bool __use_schrage = _MightOverflow && - !_OverflowOK && - _SchrageOK; -}; - -template ::__use_schrage> -struct __lce_ta; - -// 64 - -template -struct __lce_ta<__a, __c, __m, (unsigned long long)(~0), true> -{ - typedef unsigned long long result_type; - _LIBCPP_INLINE_VISIBILITY - static result_type next(result_type __x) - { - // Schrage's algorithm - const result_type __q = __m / __a; - const result_type __r = __m % __a; - const result_type __t0 = __a * (__x % __q); - const result_type __t1 = __r * (__x / __q); - __x = __t0 + (__t0 < __t1) * __m - __t1; - __x += __c - (__x >= __m - __c) * __m; - return __x; - } -}; - -template -struct __lce_ta<__a, 0, __m, (unsigned long long)(~0), true> -{ - typedef unsigned long long result_type; - _LIBCPP_INLINE_VISIBILITY - static result_type next(result_type __x) - { - // Schrage's algorithm - const result_type __q = __m / __a; - const result_type __r = __m % __a; - const result_type __t0 = __a * (__x % __q); - const result_type __t1 = __r * (__x / __q); - __x = __t0 + (__t0 < __t1) * __m - __t1; - return __x; - } -}; - -template -struct __lce_ta<__a, __c, __m, (unsigned long long)(~0), false> -{ - typedef unsigned long long result_type; - _LIBCPP_INLINE_VISIBILITY - static result_type next(result_type __x) - { - return (__a * __x + __c) % __m; - } -}; - -template -struct __lce_ta<__a, __c, 0, (unsigned long long)(~0), false> -{ - typedef unsigned long long result_type; - _LIBCPP_INLINE_VISIBILITY - static result_type next(result_type __x) - { - return __a * __x + __c; - } -}; - -// 32 - -template -struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), true> -{ - typedef unsigned result_type; - _LIBCPP_INLINE_VISIBILITY - static result_type next(result_type __x) - { - const result_type __a = static_cast(_Ap); - const result_type __c = static_cast(_Cp); - const result_type __m = static_cast(_Mp); - // Schrage's algorithm - const result_type __q = __m / __a; - const result_type __r = __m % __a; - const result_type __t0 = __a * (__x % __q); - const result_type __t1 = __r * (__x / __q); - __x = __t0 + (__t0 < __t1) * __m - __t1; - __x += __c - (__x >= __m - __c) * __m; - return __x; - } -}; - -template -struct __lce_ta<_Ap, 0, _Mp, unsigned(~0), true> -{ - typedef unsigned result_type; - _LIBCPP_INLINE_VISIBILITY - static result_type next(result_type __x) - { - const result_type __a = static_cast(_Ap); - const result_type __m = static_cast(_Mp); - // Schrage's algorithm - const result_type __q = __m / __a; - const result_type __r = __m % __a; - const result_type __t0 = __a * (__x % __q); - const result_type __t1 = __r * (__x / __q); - __x = __t0 + (__t0 < __t1) * __m - __t1; - return __x; - } -}; - -template -struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), false> -{ - typedef unsigned result_type; - _LIBCPP_INLINE_VISIBILITY - static result_type next(result_type __x) - { - const result_type __a = static_cast(_Ap); - const result_type __c = static_cast(_Cp); - const result_type __m = static_cast(_Mp); - return (__a * __x + __c) % __m; - } -}; - -template -struct __lce_ta<_Ap, _Cp, 0, unsigned(~0), false> -{ - typedef unsigned result_type; - _LIBCPP_INLINE_VISIBILITY - static result_type next(result_type __x) - { - const result_type __a = static_cast(_Ap); - const result_type __c = static_cast(_Cp); - return __a * __x + __c; - } -}; - -// 16 - -template -struct __lce_ta<__a, __c, __m, (unsigned short)(~0), __b> -{ - typedef unsigned short result_type; - _LIBCPP_INLINE_VISIBILITY - static result_type next(result_type __x) - { - return static_cast(__lce_ta<__a, __c, __m, unsigned(~0)>::next(__x)); - } -}; - -template -class _LIBCPP_TEMPLATE_VIS linear_congruential_engine; - -template -_LIBCPP_INLINE_VISIBILITY -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&); - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x); - -template -class _LIBCPP_TEMPLATE_VIS linear_congruential_engine -{ -public: - // types - typedef _UIntType result_type; - -private: - result_type __x_; - - static _LIBCPP_CONSTEXPR const result_type _Mp = result_type(~0); - - static_assert(__m == 0 || __a < __m, "linear_congruential_engine invalid parameters"); - static_assert(__m == 0 || __c < __m, "linear_congruential_engine invalid parameters"); - static_assert(is_unsigned<_UIntType>::value, "_UIntType must be unsigned type"); -public: - static _LIBCPP_CONSTEXPR const result_type _Min = __c == 0u ? 1u: 0u; - static _LIBCPP_CONSTEXPR const result_type _Max = __m - 1u; - static_assert(_Min < _Max, "linear_congruential_engine invalid parameters"); - - // engine characteristics - static _LIBCPP_CONSTEXPR const result_type multiplier = __a; - static _LIBCPP_CONSTEXPR const result_type increment = __c; - static _LIBCPP_CONSTEXPR const result_type modulus = __m; - _LIBCPP_INLINE_VISIBILITY - static _LIBCPP_CONSTEXPR result_type min() {return _Min;} - _LIBCPP_INLINE_VISIBILITY - static _LIBCPP_CONSTEXPR result_type max() {return _Max;} - static _LIBCPP_CONSTEXPR const result_type default_seed = 1u; - - // constructors and seeding functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - linear_congruential_engine() : linear_congruential_engine(default_seed) {} - _LIBCPP_INLINE_VISIBILITY - explicit linear_congruential_engine(result_type __s) { seed(__s); } -#else - _LIBCPP_INLINE_VISIBILITY - explicit linear_congruential_engine(result_type __s = default_seed) { - seed(__s); - } -#endif - template - _LIBCPP_INLINE_VISIBILITY - explicit linear_congruential_engine(_Sseq& __q, - typename enable_if<__is_seed_sequence<_Sseq, linear_congruential_engine>::value>::type* = 0) - {seed(__q);} - _LIBCPP_INLINE_VISIBILITY - void seed(result_type __s = default_seed) - {seed(integral_constant(), - integral_constant(), __s);} - template - _LIBCPP_INLINE_VISIBILITY - typename enable_if - < - __is_seed_sequence<_Sseq, linear_congruential_engine>::value, - void - >::type - seed(_Sseq& __q) - {__seed(__q, integral_constant 0x100000000ull))>());} - - // generating functions - _LIBCPP_INLINE_VISIBILITY - result_type operator()() - {return __x_ = static_cast(__lce_ta<__a, __c, __m, _Mp>::next(__x_));} - _LIBCPP_INLINE_VISIBILITY - void discard(unsigned long long __z) {for (; __z; --__z) operator()();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const linear_congruential_engine& __x, - const linear_congruential_engine& __y) - {return __x.__x_ == __y.__x_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const linear_congruential_engine& __x, - const linear_congruential_engine& __y) - {return !(__x == __y);} - -private: - - _LIBCPP_INLINE_VISIBILITY - void seed(true_type, true_type, result_type __s) {__x_ = __s == 0 ? 1 : __s;} - _LIBCPP_INLINE_VISIBILITY - void seed(true_type, false_type, result_type __s) {__x_ = __s;} - _LIBCPP_INLINE_VISIBILITY - void seed(false_type, true_type, result_type __s) {__x_ = __s % __m == 0 ? - 1 : __s % __m;} - _LIBCPP_INLINE_VISIBILITY - void seed(false_type, false_type, result_type __s) {__x_ = __s % __m;} - - template - void __seed(_Sseq& __q, integral_constant); - template - void __seed(_Sseq& __q, integral_constant); - - template - friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, - const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&); - - template - friend - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, - linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x); -}; - -template - _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type - linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier; - -template - _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type - linear_congruential_engine<_UIntType, __a, __c, __m>::increment; - -template - _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type - linear_congruential_engine<_UIntType, __a, __c, __m>::modulus; - -template - _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type - linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed; - -template -template -void -linear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q, - integral_constant) -{ - const unsigned __k = 1; - uint32_t __ar[__k+3]; - __q.generate(__ar, __ar + __k + 3); - result_type __s = static_cast(__ar[3] % __m); - __x_ = __c == 0 && __s == 0 ? result_type(1) : __s; -} - -template -template -void -linear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q, - integral_constant) -{ - const unsigned __k = 2; - uint32_t __ar[__k+3]; - __q.generate(__ar, __ar + __k + 3); - result_type __s = static_cast((__ar[3] + - ((uint64_t)__ar[4] << 32)) % __m); - __x_ = __c == 0 && __s == 0 ? result_type(1) : __s; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const linear_congruential_engine<_UIntType, __a, __c, __m>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _Ostream; - __os.flags(_Ostream::dec | _Ostream::left); - __os.fill(__os.widen(' ')); - return __os << __x.__x_; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - linear_congruential_engine<_UIntType, __a, __c, __m>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - _UIntType __t; - __is >> __t; - if (!__is.fail()) - __x.__x_ = __t; - return __is; -} - -typedef linear_congruential_engine - minstd_rand0; -typedef linear_congruential_engine - minstd_rand; -typedef minstd_rand default_random_engine; -// mersenne_twister_engine - -template -class _LIBCPP_TEMPLATE_VIS mersenne_twister_engine; - -template -bool -operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __x, - const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __y); - -template -_LIBCPP_INLINE_VISIBILITY -bool -operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __x, - const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __y); - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __x); - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __x); - -template -class _LIBCPP_TEMPLATE_VIS mersenne_twister_engine -{ -public: - // types - typedef _UIntType result_type; - -private: - result_type __x_[__n]; - size_t __i_; - - static_assert( 0 < __m, "mersenne_twister_engine invalid parameters"); - static_assert(__m <= __n, "mersenne_twister_engine invalid parameters"); - static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits::digits; - static_assert(__w <= _Dt, "mersenne_twister_engine invalid parameters"); - static_assert( 2 <= __w, "mersenne_twister_engine invalid parameters"); - static_assert(__r <= __w, "mersenne_twister_engine invalid parameters"); - static_assert(__u <= __w, "mersenne_twister_engine invalid parameters"); - static_assert(__s <= __w, "mersenne_twister_engine invalid parameters"); - static_assert(__t <= __w, "mersenne_twister_engine invalid parameters"); - static_assert(__l <= __w, "mersenne_twister_engine invalid parameters"); -public: - static _LIBCPP_CONSTEXPR const result_type _Min = 0; - static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) : - (result_type(1) << __w) - result_type(1); - static_assert(_Min < _Max, "mersenne_twister_engine invalid parameters"); - static_assert(__a <= _Max, "mersenne_twister_engine invalid parameters"); - static_assert(__b <= _Max, "mersenne_twister_engine invalid parameters"); - static_assert(__c <= _Max, "mersenne_twister_engine invalid parameters"); - static_assert(__d <= _Max, "mersenne_twister_engine invalid parameters"); - static_assert(__f <= _Max, "mersenne_twister_engine invalid parameters"); - - // engine characteristics - static _LIBCPP_CONSTEXPR const size_t word_size = __w; - static _LIBCPP_CONSTEXPR const size_t state_size = __n; - static _LIBCPP_CONSTEXPR const size_t shift_size = __m; - static _LIBCPP_CONSTEXPR const size_t mask_bits = __r; - static _LIBCPP_CONSTEXPR const result_type xor_mask = __a; - static _LIBCPP_CONSTEXPR const size_t tempering_u = __u; - static _LIBCPP_CONSTEXPR const result_type tempering_d = __d; - static _LIBCPP_CONSTEXPR const size_t tempering_s = __s; - static _LIBCPP_CONSTEXPR const result_type tempering_b = __b; - static _LIBCPP_CONSTEXPR const size_t tempering_t = __t; - static _LIBCPP_CONSTEXPR const result_type tempering_c = __c; - static _LIBCPP_CONSTEXPR const size_t tempering_l = __l; - static _LIBCPP_CONSTEXPR const result_type initialization_multiplier = __f; - _LIBCPP_INLINE_VISIBILITY - static _LIBCPP_CONSTEXPR result_type min() { return _Min; } - _LIBCPP_INLINE_VISIBILITY - static _LIBCPP_CONSTEXPR result_type max() { return _Max; } - static _LIBCPP_CONSTEXPR const result_type default_seed = 5489u; - - // constructors and seeding functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - mersenne_twister_engine() : mersenne_twister_engine(default_seed) {} - _LIBCPP_INLINE_VISIBILITY - explicit mersenne_twister_engine(result_type __sd) { seed(__sd); } -#else - _LIBCPP_INLINE_VISIBILITY - explicit mersenne_twister_engine(result_type __sd = default_seed) { - seed(__sd); - } -#endif - template - _LIBCPP_INLINE_VISIBILITY - explicit mersenne_twister_engine(_Sseq& __q, - typename enable_if<__is_seed_sequence<_Sseq, mersenne_twister_engine>::value>::type* = 0) - {seed(__q);} - void seed(result_type __sd = default_seed); - template - _LIBCPP_INLINE_VISIBILITY - typename enable_if - < - __is_seed_sequence<_Sseq, mersenne_twister_engine>::value, - void - >::type - seed(_Sseq& __q) - {__seed(__q, integral_constant());} - - // generating functions - result_type operator()(); - _LIBCPP_INLINE_VISIBILITY - void discard(unsigned long long __z) {for (; __z; --__z) operator()();} - - template - friend - bool - operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __x, - const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __y); - - template - friend - bool - operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __x, - const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __y); - - template - friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, - const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __x); - - template - friend - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, - mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __x); -private: - - template - void __seed(_Sseq& __q, integral_constant); - template - void __seed(_Sseq& __q, integral_constant); - - template - _LIBCPP_INLINE_VISIBILITY - static - typename enable_if - < - __count < __w, - result_type - >::type - __lshift(result_type __x) {return (__x << __count) & _Max;} - - template - _LIBCPP_INLINE_VISIBILITY - static - typename enable_if - < - (__count >= __w), - result_type - >::type - __lshift(result_type) {return result_type(0);} - - template - _LIBCPP_INLINE_VISIBILITY - static - typename enable_if - < - __count < _Dt, - result_type - >::type - __rshift(result_type __x) {return __x >> __count;} - - template - _LIBCPP_INLINE_VISIBILITY - static - typename enable_if - < - (__count >= _Dt), - result_type - >::type - __rshift(result_type) {return result_type(0);} -}; - -template - _LIBCPP_CONSTEXPR const size_t - mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::word_size; - -template - _LIBCPP_CONSTEXPR const size_t - mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::state_size; - -template - _LIBCPP_CONSTEXPR const size_t - mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::shift_size; - -template - _LIBCPP_CONSTEXPR const size_t - mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::mask_bits; - -template - _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type - mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::xor_mask; - -template - _LIBCPP_CONSTEXPR const size_t - mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_u; - -template - _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type - mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_d; - -template - _LIBCPP_CONSTEXPR const size_t - mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_s; - -template - _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type - mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_b; - -template - _LIBCPP_CONSTEXPR const size_t - mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_t; - -template - _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type - mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_c; - -template - _LIBCPP_CONSTEXPR const size_t - mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_l; - -template - _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type - mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::initialization_multiplier; - -template - _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type - mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::default_seed; - -template -void -mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, - __t, __c, __l, __f>::seed(result_type __sd) - _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK -{ // __w >= 2 - __x_[0] = __sd & _Max; - for (size_t __i = 1; __i < __n; ++__i) - __x_[__i] = (__f * (__x_[__i-1] ^ __rshift<__w - 2>(__x_[__i-1])) + __i) & _Max; - __i_ = 0; -} - -template -template -void -mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, - __t, __c, __l, __f>::__seed(_Sseq& __q, integral_constant) -{ - const unsigned __k = 1; - uint32_t __ar[__n * __k]; - __q.generate(__ar, __ar + __n * __k); - for (size_t __i = 0; __i < __n; ++__i) - __x_[__i] = static_cast(__ar[__i] & _Max); - const result_type __mask = __r == _Dt ? result_type(~0) : - (result_type(1) << __r) - result_type(1); - __i_ = 0; - if ((__x_[0] & ~__mask) == 0) - { - for (size_t __i = 1; __i < __n; ++__i) - if (__x_[__i] != 0) - return; - __x_[0] = result_type(1) << (__w - 1); - } -} - -template -template -void -mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, - __t, __c, __l, __f>::__seed(_Sseq& __q, integral_constant) -{ - const unsigned __k = 2; - uint32_t __ar[__n * __k]; - __q.generate(__ar, __ar + __n * __k); - for (size_t __i = 0; __i < __n; ++__i) - __x_[__i] = static_cast( - (__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max); - const result_type __mask = __r == _Dt ? result_type(~0) : - (result_type(1) << __r) - result_type(1); - __i_ = 0; - if ((__x_[0] & ~__mask) == 0) - { - for (size_t __i = 1; __i < __n; ++__i) - if (__x_[__i] != 0) - return; - __x_[0] = result_type(1) << (__w - 1); - } -} - -template -_UIntType -mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, - __t, __c, __l, __f>::operator()() -{ - const size_t __j = (__i_ + 1) % __n; - const result_type __mask = __r == _Dt ? result_type(~0) : - (result_type(1) << __r) - result_type(1); - const result_type _Yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask); - const size_t __k = (__i_ + __m) % __n; - __x_[__i_] = __x_[__k] ^ __rshift<1>(_Yp) ^ (__a * (_Yp & 1)); - result_type __z = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d); - __i_ = __j; - __z ^= __lshift<__s>(__z) & __b; - __z ^= __lshift<__t>(__z) & __c; - return __z ^ __rshift<__l>(__z); -} - -template -bool -operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __x, - const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __y) -{ - if (__x.__i_ == __y.__i_) - return _VSTD::equal(__x.__x_, __x.__x_ + _Np, __y.__x_); - if (__x.__i_ == 0 || __y.__i_ == 0) - { - size_t __j = _VSTD::min(_Np - __x.__i_, _Np - __y.__i_); - if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + __x.__i_ + __j, - __y.__x_ + __y.__i_)) - return false; - if (__x.__i_ == 0) - return _VSTD::equal(__x.__x_ + __j, __x.__x_ + _Np, __y.__x_); - return _VSTD::equal(__x.__x_, __x.__x_ + (_Np - __j), __y.__x_ + __j); - } - if (__x.__i_ < __y.__i_) - { - size_t __j = _Np - __y.__i_; - if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + (__x.__i_ + __j), - __y.__x_ + __y.__i_)) - return false; - if (!_VSTD::equal(__x.__x_ + (__x.__i_ + __j), __x.__x_ + _Np, - __y.__x_)) - return false; - return _VSTD::equal(__x.__x_, __x.__x_ + __x.__i_, - __y.__x_ + (_Np - (__x.__i_ + __j))); - } - size_t __j = _Np - __x.__i_; - if (!_VSTD::equal(__y.__x_ + __y.__i_, __y.__x_ + (__y.__i_ + __j), - __x.__x_ + __x.__i_)) - return false; - if (!_VSTD::equal(__y.__x_ + (__y.__i_ + __j), __y.__x_ + _Np, - __x.__x_)) - return false; - return _VSTD::equal(__y.__x_, __y.__x_ + __y.__i_, - __x.__x_ + (_Np - (__y.__i_ + __j))); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __x, - const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __y) -{ - return !(__x == __y); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _Ostream; - __os.flags(_Ostream::dec | _Ostream::left); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - __os << __x.__x_[__x.__i_]; - for (size_t __j = __x.__i_ + 1; __j < _Np; ++__j) - __os << __sp << __x.__x_[__j]; - for (size_t __j = 0; __j < __x.__i_; ++__j) - __os << __sp << __x.__x_[__j]; - return __os; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, - _Bp, _Tp, _Cp, _Lp, _Fp>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - _UInt __t[_Np]; - for (size_t __i = 0; __i < _Np; ++__i) - __is >> __t[__i]; - if (!__is.fail()) - { - for (size_t __i = 0; __i < _Np; ++__i) - __x.__x_[__i] = __t[__i]; - __x.__i_ = 0; - } - return __is; -} - -typedef mersenne_twister_engine mt19937; -typedef mersenne_twister_engine mt19937_64; - -// subtract_with_carry_engine - -template -class _LIBCPP_TEMPLATE_VIS subtract_with_carry_engine; - -template -bool -operator==( - const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x, - const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y); - -template -_LIBCPP_INLINE_VISIBILITY -bool -operator!=( - const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x, - const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y); - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x); - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x); - -template -class _LIBCPP_TEMPLATE_VIS subtract_with_carry_engine -{ -public: - // types - typedef _UIntType result_type; - -private: - result_type __x_[__r]; - result_type __c_; - size_t __i_; - - static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits::digits; - static_assert( 0 < __w, "subtract_with_carry_engine invalid parameters"); - static_assert(__w <= _Dt, "subtract_with_carry_engine invalid parameters"); - static_assert( 0 < __s, "subtract_with_carry_engine invalid parameters"); - static_assert(__s < __r, "subtract_with_carry_engine invalid parameters"); -public: - static _LIBCPP_CONSTEXPR const result_type _Min = 0; - static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) : - (result_type(1) << __w) - result_type(1); - static_assert(_Min < _Max, "subtract_with_carry_engine invalid parameters"); - - // engine characteristics - static _LIBCPP_CONSTEXPR const size_t word_size = __w; - static _LIBCPP_CONSTEXPR const size_t short_lag = __s; - static _LIBCPP_CONSTEXPR const size_t long_lag = __r; - _LIBCPP_INLINE_VISIBILITY - static _LIBCPP_CONSTEXPR result_type min() { return _Min; } - _LIBCPP_INLINE_VISIBILITY - static _LIBCPP_CONSTEXPR result_type max() { return _Max; } - static _LIBCPP_CONSTEXPR const result_type default_seed = 19780503u; - - // constructors and seeding functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - subtract_with_carry_engine() : subtract_with_carry_engine(default_seed) {} - _LIBCPP_INLINE_VISIBILITY - explicit subtract_with_carry_engine(result_type __sd) { seed(__sd); } -#else - _LIBCPP_INLINE_VISIBILITY - explicit subtract_with_carry_engine(result_type __sd = default_seed) { - seed(__sd); - } -#endif - template - _LIBCPP_INLINE_VISIBILITY - explicit subtract_with_carry_engine(_Sseq& __q, - typename enable_if<__is_seed_sequence<_Sseq, subtract_with_carry_engine>::value>::type* = 0) - {seed(__q);} - _LIBCPP_INLINE_VISIBILITY - void seed(result_type __sd = default_seed) - {seed(__sd, integral_constant());} - template - _LIBCPP_INLINE_VISIBILITY - typename enable_if - < - __is_seed_sequence<_Sseq, subtract_with_carry_engine>::value, - void - >::type - seed(_Sseq& __q) - {__seed(__q, integral_constant());} - - // generating functions - result_type operator()(); - _LIBCPP_INLINE_VISIBILITY - void discard(unsigned long long __z) {for (; __z; --__z) operator()();} - - template - friend - bool - operator==( - const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x, - const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y); - - template - friend - bool - operator!=( - const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x, - const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y); - - template - friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, - const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x); - - template - friend - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, - subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x); - -private: - - void seed(result_type __sd, integral_constant); - void seed(result_type __sd, integral_constant); - template - void __seed(_Sseq& __q, integral_constant); - template - void __seed(_Sseq& __q, integral_constant); -}; - -template - _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::word_size; - -template - _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::short_lag; - -template - _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::long_lag; - -template - _LIBCPP_CONSTEXPR const typename subtract_with_carry_engine<_UIntType, __w, __s, __r>::result_type - subtract_with_carry_engine<_UIntType, __w, __s, __r>::default_seed; - -template -void -subtract_with_carry_engine<_UIntType, __w, __s, __r>::seed(result_type __sd, - integral_constant) -{ - linear_congruential_engine - __e(__sd == 0u ? default_seed : __sd); - for (size_t __i = 0; __i < __r; ++__i) - __x_[__i] = static_cast(__e() & _Max); - __c_ = __x_[__r-1] == 0; - __i_ = 0; -} - -template -void -subtract_with_carry_engine<_UIntType, __w, __s, __r>::seed(result_type __sd, - integral_constant) -{ - linear_congruential_engine - __e(__sd == 0u ? default_seed : __sd); - for (size_t __i = 0; __i < __r; ++__i) - { - result_type __e0 = __e(); - __x_[__i] = static_cast( - (__e0 + ((uint64_t)__e() << 32)) & _Max); - } - __c_ = __x_[__r-1] == 0; - __i_ = 0; -} - -template -template -void -subtract_with_carry_engine<_UIntType, __w, __s, __r>::__seed(_Sseq& __q, - integral_constant) -{ - const unsigned __k = 1; - uint32_t __ar[__r * __k]; - __q.generate(__ar, __ar + __r * __k); - for (size_t __i = 0; __i < __r; ++__i) - __x_[__i] = static_cast(__ar[__i] & _Max); - __c_ = __x_[__r-1] == 0; - __i_ = 0; -} - -template -template -void -subtract_with_carry_engine<_UIntType, __w, __s, __r>::__seed(_Sseq& __q, - integral_constant) -{ - const unsigned __k = 2; - uint32_t __ar[__r * __k]; - __q.generate(__ar, __ar + __r * __k); - for (size_t __i = 0; __i < __r; ++__i) - __x_[__i] = static_cast( - (__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max); - __c_ = __x_[__r-1] == 0; - __i_ = 0; -} - -template -_UIntType -subtract_with_carry_engine<_UIntType, __w, __s, __r>::operator()() -{ - const result_type& __xs = __x_[(__i_ + (__r - __s)) % __r]; - result_type& __xr = __x_[__i_]; - result_type __new_c = __c_ == 0 ? __xs < __xr : __xs != 0 ? __xs <= __xr : 1; - __xr = (__xs - __xr - __c_) & _Max; - __c_ = __new_c; - __i_ = (__i_ + 1) % __r; - return __xr; -} - -template -bool -operator==( - const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x, - const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y) -{ - if (__x.__c_ != __y.__c_) - return false; - if (__x.__i_ == __y.__i_) - return _VSTD::equal(__x.__x_, __x.__x_ + _Rp, __y.__x_); - if (__x.__i_ == 0 || __y.__i_ == 0) - { - size_t __j = _VSTD::min(_Rp - __x.__i_, _Rp - __y.__i_); - if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + __x.__i_ + __j, - __y.__x_ + __y.__i_)) - return false; - if (__x.__i_ == 0) - return _VSTD::equal(__x.__x_ + __j, __x.__x_ + _Rp, __y.__x_); - return _VSTD::equal(__x.__x_, __x.__x_ + (_Rp - __j), __y.__x_ + __j); - } - if (__x.__i_ < __y.__i_) - { - size_t __j = _Rp - __y.__i_; - if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + (__x.__i_ + __j), - __y.__x_ + __y.__i_)) - return false; - if (!_VSTD::equal(__x.__x_ + (__x.__i_ + __j), __x.__x_ + _Rp, - __y.__x_)) - return false; - return _VSTD::equal(__x.__x_, __x.__x_ + __x.__i_, - __y.__x_ + (_Rp - (__x.__i_ + __j))); - } - size_t __j = _Rp - __x.__i_; - if (!_VSTD::equal(__y.__x_ + __y.__i_, __y.__x_ + (__y.__i_ + __j), - __x.__x_ + __x.__i_)) - return false; - if (!_VSTD::equal(__y.__x_ + (__y.__i_ + __j), __y.__x_ + _Rp, - __x.__x_)) - return false; - return _VSTD::equal(__y.__x_, __y.__x_ + __y.__i_, - __x.__x_ + (_Rp - (__y.__i_ + __j))); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=( - const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x, - const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y) -{ - return !(__x == __y); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _Ostream; - __os.flags(_Ostream::dec | _Ostream::left); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - __os << __x.__x_[__x.__i_]; - for (size_t __j = __x.__i_ + 1; __j < _Rp; ++__j) - __os << __sp << __x.__x_[__j]; - for (size_t __j = 0; __j < __x.__i_; ++__j) - __os << __sp << __x.__x_[__j]; - __os << __sp << __x.__c_; - return __os; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - _UInt __t[_Rp+1]; - for (size_t __i = 0; __i < _Rp+1; ++__i) - __is >> __t[__i]; - if (!__is.fail()) - { - for (size_t __i = 0; __i < _Rp; ++__i) - __x.__x_[__i] = __t[__i]; - __x.__c_ = __t[_Rp]; - __x.__i_ = 0; - } - return __is; -} - -typedef subtract_with_carry_engine ranlux24_base; -typedef subtract_with_carry_engine ranlux48_base; - -// discard_block_engine - -template -class _LIBCPP_TEMPLATE_VIS discard_block_engine -{ - _Engine __e_; - int __n_; - - static_assert( 0 < __r, "discard_block_engine invalid parameters"); - static_assert(__r <= __p, "discard_block_engine invalid parameters"); - static_assert(__r <= INT_MAX, "discard_block_engine invalid parameters"); -public: - // types - typedef typename _Engine::result_type result_type; - - // engine characteristics - static _LIBCPP_CONSTEXPR const size_t block_size = __p; - static _LIBCPP_CONSTEXPR const size_t used_block = __r; - -#ifdef _LIBCPP_CXX03_LANG - static const result_type _Min = _Engine::_Min; - static const result_type _Max = _Engine::_Max; -#else - static _LIBCPP_CONSTEXPR const result_type _Min = _Engine::min(); - static _LIBCPP_CONSTEXPR const result_type _Max = _Engine::max(); -#endif - - _LIBCPP_INLINE_VISIBILITY - static _LIBCPP_CONSTEXPR result_type min() { return _Engine::min(); } - _LIBCPP_INLINE_VISIBILITY - static _LIBCPP_CONSTEXPR result_type max() { return _Engine::max(); } - - // constructors and seeding functions - _LIBCPP_INLINE_VISIBILITY - discard_block_engine() : __n_(0) {} - _LIBCPP_INLINE_VISIBILITY - explicit discard_block_engine(const _Engine& __e) - : __e_(__e), __n_(0) {} -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - explicit discard_block_engine(_Engine&& __e) - : __e_(_VSTD::move(__e)), __n_(0) {} -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - explicit discard_block_engine(result_type __sd) : __e_(__sd), __n_(0) {} - template - _LIBCPP_INLINE_VISIBILITY - explicit discard_block_engine(_Sseq& __q, - typename enable_if<__is_seed_sequence<_Sseq, discard_block_engine>::value && - !is_convertible<_Sseq, _Engine>::value>::type* = 0) - : __e_(__q), __n_(0) {} - _LIBCPP_INLINE_VISIBILITY - void seed() {__e_.seed(); __n_ = 0;} - _LIBCPP_INLINE_VISIBILITY - void seed(result_type __sd) {__e_.seed(__sd); __n_ = 0;} - template - _LIBCPP_INLINE_VISIBILITY - typename enable_if - < - __is_seed_sequence<_Sseq, discard_block_engine>::value, - void - >::type - seed(_Sseq& __q) {__e_.seed(__q); __n_ = 0;} - - // generating functions - result_type operator()(); - _LIBCPP_INLINE_VISIBILITY - void discard(unsigned long long __z) {for (; __z; --__z) operator()();} - - // property functions - _LIBCPP_INLINE_VISIBILITY - const _Engine& base() const _NOEXCEPT {return __e_;} - - template - friend - bool - operator==( - const discard_block_engine<_Eng, _Pp, _Rp>& __x, - const discard_block_engine<_Eng, _Pp, _Rp>& __y); - - template - friend - bool - operator!=( - const discard_block_engine<_Eng, _Pp, _Rp>& __x, - const discard_block_engine<_Eng, _Pp, _Rp>& __y); - - template - friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, - const discard_block_engine<_Eng, _Pp, _Rp>& __x); - - template - friend - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, - discard_block_engine<_Eng, _Pp, _Rp>& __x); -}; - -template - _LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::block_size; - -template - _LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::used_block; - -template -typename discard_block_engine<_Engine, __p, __r>::result_type -discard_block_engine<_Engine, __p, __r>::operator()() -{ - if (__n_ >= static_cast(__r)) - { - __e_.discard(__p - __r); - __n_ = 0; - } - ++__n_; - return __e_(); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(const discard_block_engine<_Eng, _Pp, _Rp>& __x, - const discard_block_engine<_Eng, _Pp, _Rp>& __y) -{ - return __x.__n_ == __y.__n_ && __x.__e_ == __y.__e_; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const discard_block_engine<_Eng, _Pp, _Rp>& __x, - const discard_block_engine<_Eng, _Pp, _Rp>& __y) -{ - return !(__x == __y); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const discard_block_engine<_Eng, _Pp, _Rp>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _Ostream; - __os.flags(_Ostream::dec | _Ostream::left); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - return __os << __x.__e_ << __sp << __x.__n_; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - discard_block_engine<_Eng, _Pp, _Rp>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - _Eng __e; - int __n; - __is >> __e >> __n; - if (!__is.fail()) - { - __x.__e_ = __e; - __x.__n_ = __n; - } - return __is; -} - -typedef discard_block_engine ranlux24; -typedef discard_block_engine ranlux48; - -// independent_bits_engine - -template -class _LIBCPP_TEMPLATE_VIS independent_bits_engine -{ - template - class __get_n - { - static _LIBCPP_CONSTEXPR const size_t _Dt = numeric_limits<_UInt>::digits; - static _LIBCPP_CONSTEXPR const size_t _Np = _Wp / _Mp + (_Wp % _Mp != 0); - static _LIBCPP_CONSTEXPR const size_t _W0 = _Wp / _Np; - static _LIBCPP_CONSTEXPR const _UInt _Y0 = _W0 >= _Dt ? 0 : (_R0 >> _W0) << _W0; - public: - static _LIBCPP_CONSTEXPR const size_t value = _R0 - _Y0 > _Y0 / _Np ? _Np + 1 : _Np; - }; -public: - // types - typedef _UIntType result_type; - -private: - _Engine __e_; - - static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits::digits; - static_assert( 0 < __w, "independent_bits_engine invalid parameters"); - static_assert(__w <= _Dt, "independent_bits_engine invalid parameters"); - - typedef typename _Engine::result_type _Engine_result_type; - typedef typename conditional - < - sizeof(_Engine_result_type) <= sizeof(result_type), - result_type, - _Engine_result_type - >::type _Working_result_type; -#ifdef _LIBCPP_CXX03_LANG - static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min - + _Working_result_type(1); -#else - static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min() - + _Working_result_type(1); -#endif - static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value; - static _LIBCPP_CONSTEXPR const size_t __n = __get_n<_Working_result_type, _Rp, __w, __m>::value; - static _LIBCPP_CONSTEXPR const size_t __w0 = __w / __n; - static _LIBCPP_CONSTEXPR const size_t __n0 = __n - __w % __n; - static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits; - static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits; - static _LIBCPP_CONSTEXPR const _Working_result_type __y0 = __w0 >= _WDt ? 0 : - (_Rp >> __w0) << __w0; - static _LIBCPP_CONSTEXPR const _Working_result_type __y1 = __w0 >= _WDt - 1 ? 0 : - (_Rp >> (__w0+1)) << (__w0+1); - static _LIBCPP_CONSTEXPR const _Engine_result_type __mask0 = __w0 > 0 ? - _Engine_result_type(~0) >> (_EDt - __w0) : - _Engine_result_type(0); - static _LIBCPP_CONSTEXPR const _Engine_result_type __mask1 = __w0 < _EDt - 1 ? - _Engine_result_type(~0) >> (_EDt - (__w0 + 1)) : - _Engine_result_type(~0); -public: - static _LIBCPP_CONSTEXPR const result_type _Min = 0; - static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) : - (result_type(1) << __w) - result_type(1); - static_assert(_Min < _Max, "independent_bits_engine invalid parameters"); - - // engine characteristics - _LIBCPP_INLINE_VISIBILITY - static _LIBCPP_CONSTEXPR result_type min() { return _Min; } - _LIBCPP_INLINE_VISIBILITY - static _LIBCPP_CONSTEXPR result_type max() { return _Max; } - - // constructors and seeding functions - _LIBCPP_INLINE_VISIBILITY - independent_bits_engine() {} - _LIBCPP_INLINE_VISIBILITY - explicit independent_bits_engine(const _Engine& __e) - : __e_(__e) {} -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - explicit independent_bits_engine(_Engine&& __e) - : __e_(_VSTD::move(__e)) {} -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - explicit independent_bits_engine(result_type __sd) : __e_(__sd) {} - template - _LIBCPP_INLINE_VISIBILITY - explicit independent_bits_engine(_Sseq& __q, - typename enable_if<__is_seed_sequence<_Sseq, independent_bits_engine>::value && - !is_convertible<_Sseq, _Engine>::value>::type* = 0) - : __e_(__q) {} - _LIBCPP_INLINE_VISIBILITY - void seed() {__e_.seed();} - _LIBCPP_INLINE_VISIBILITY - void seed(result_type __sd) {__e_.seed(__sd);} - template - _LIBCPP_INLINE_VISIBILITY - typename enable_if - < - __is_seed_sequence<_Sseq, independent_bits_engine>::value, - void - >::type - seed(_Sseq& __q) {__e_.seed(__q);} - - // generating functions - _LIBCPP_INLINE_VISIBILITY - result_type operator()() {return __eval(integral_constant());} - _LIBCPP_INLINE_VISIBILITY - void discard(unsigned long long __z) {for (; __z; --__z) operator()();} - - // property functions - _LIBCPP_INLINE_VISIBILITY - const _Engine& base() const _NOEXCEPT {return __e_;} - - template - friend - bool - operator==( - const independent_bits_engine<_Eng, _Wp, _UInt>& __x, - const independent_bits_engine<_Eng, _Wp, _UInt>& __y); - - template - friend - bool - operator!=( - const independent_bits_engine<_Eng, _Wp, _UInt>& __x, - const independent_bits_engine<_Eng, _Wp, _UInt>& __y); - - template - friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, - const independent_bits_engine<_Eng, _Wp, _UInt>& __x); - - template - friend - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, - independent_bits_engine<_Eng, _Wp, _UInt>& __x); - -private: - _LIBCPP_INLINE_VISIBILITY - result_type __eval(false_type); - result_type __eval(true_type); - - template - _LIBCPP_INLINE_VISIBILITY - static - typename enable_if - < - __count < _Dt, - result_type - >::type - __lshift(result_type __x) {return __x << __count;} - - template - _LIBCPP_INLINE_VISIBILITY - static - typename enable_if - < - (__count >= _Dt), - result_type - >::type - __lshift(result_type) {return result_type(0);} -}; - -template -inline -_UIntType -independent_bits_engine<_Engine, __w, _UIntType>::__eval(false_type) -{ - return static_cast(__e_() & __mask0); -} - -template -_UIntType -independent_bits_engine<_Engine, __w, _UIntType>::__eval(true_type) -{ - result_type _Sp = 0; - for (size_t __k = 0; __k < __n0; ++__k) - { - _Engine_result_type __u; - do - { - __u = __e_() - _Engine::min(); - } while (__u >= __y0); - _Sp = static_cast(__lshift<__w0>(_Sp) + (__u & __mask0)); - } - for (size_t __k = __n0; __k < __n; ++__k) - { - _Engine_result_type __u; - do - { - __u = __e_() - _Engine::min(); - } while (__u >= __y1); - _Sp = static_cast(__lshift<__w0+1>(_Sp) + (__u & __mask1)); - } - return _Sp; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==( - const independent_bits_engine<_Eng, _Wp, _UInt>& __x, - const independent_bits_engine<_Eng, _Wp, _UInt>& __y) -{ - return __x.base() == __y.base(); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=( - const independent_bits_engine<_Eng, _Wp, _UInt>& __x, - const independent_bits_engine<_Eng, _Wp, _UInt>& __y) -{ - return !(__x == __y); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const independent_bits_engine<_Eng, _Wp, _UInt>& __x) -{ - return __os << __x.base(); -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - independent_bits_engine<_Eng, _Wp, _UInt>& __x) -{ - _Eng __e; - __is >> __e; - if (!__is.fail()) - __x.__e_ = __e; - return __is; -} - -// shuffle_order_engine - -template -struct __ugcd -{ - static _LIBCPP_CONSTEXPR const uint64_t value = __ugcd<_Yp, _Xp % _Yp>::value; -}; - -template -struct __ugcd<_Xp, 0> -{ - static _LIBCPP_CONSTEXPR const uint64_t value = _Xp; -}; - -template -class __uratio -{ - static_assert(_Dp != 0, "__uratio divide by 0"); - static _LIBCPP_CONSTEXPR const uint64_t __gcd = __ugcd<_Np, _Dp>::value; -public: - static _LIBCPP_CONSTEXPR const uint64_t num = _Np / __gcd; - static _LIBCPP_CONSTEXPR const uint64_t den = _Dp / __gcd; - - typedef __uratio type; -}; - -template -class _LIBCPP_TEMPLATE_VIS shuffle_order_engine -{ - static_assert(0 < __k, "shuffle_order_engine invalid parameters"); -public: - // types - typedef typename _Engine::result_type result_type; - -private: - _Engine __e_; - result_type _V_[__k]; - result_type _Y_; - -public: - // engine characteristics - static _LIBCPP_CONSTEXPR const size_t table_size = __k; - -#ifdef _LIBCPP_CXX03_LANG - static const result_type _Min = _Engine::_Min; - static const result_type _Max = _Engine::_Max; -#else - static _LIBCPP_CONSTEXPR const result_type _Min = _Engine::min(); - static _LIBCPP_CONSTEXPR const result_type _Max = _Engine::max(); -#endif - static_assert(_Min < _Max, "shuffle_order_engine invalid parameters"); - _LIBCPP_INLINE_VISIBILITY - static _LIBCPP_CONSTEXPR result_type min() { return _Min; } - _LIBCPP_INLINE_VISIBILITY - static _LIBCPP_CONSTEXPR result_type max() { return _Max; } - - static _LIBCPP_CONSTEXPR const unsigned long long _Rp = _Max - _Min + 1ull; - - // constructors and seeding functions - _LIBCPP_INLINE_VISIBILITY - shuffle_order_engine() {__init();} - _LIBCPP_INLINE_VISIBILITY - explicit shuffle_order_engine(const _Engine& __e) - : __e_(__e) {__init();} -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - explicit shuffle_order_engine(_Engine&& __e) - : __e_(_VSTD::move(__e)) {__init();} -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - explicit shuffle_order_engine(result_type __sd) : __e_(__sd) {__init();} - template - _LIBCPP_INLINE_VISIBILITY - explicit shuffle_order_engine(_Sseq& __q, - typename enable_if<__is_seed_sequence<_Sseq, shuffle_order_engine>::value && - !is_convertible<_Sseq, _Engine>::value>::type* = 0) - : __e_(__q) {__init();} - _LIBCPP_INLINE_VISIBILITY - void seed() {__e_.seed(); __init();} - _LIBCPP_INLINE_VISIBILITY - void seed(result_type __sd) {__e_.seed(__sd); __init();} - template - _LIBCPP_INLINE_VISIBILITY - typename enable_if - < - __is_seed_sequence<_Sseq, shuffle_order_engine>::value, - void - >::type - seed(_Sseq& __q) {__e_.seed(__q); __init();} - - // generating functions - _LIBCPP_INLINE_VISIBILITY - result_type operator()() {return __eval(integral_constant());} - _LIBCPP_INLINE_VISIBILITY - void discard(unsigned long long __z) {for (; __z; --__z) operator()();} - - // property functions - _LIBCPP_INLINE_VISIBILITY - const _Engine& base() const _NOEXCEPT {return __e_;} - -private: - template - friend - bool - operator==( - const shuffle_order_engine<_Eng, _Kp>& __x, - const shuffle_order_engine<_Eng, _Kp>& __y); - - template - friend - bool - operator!=( - const shuffle_order_engine<_Eng, _Kp>& __x, - const shuffle_order_engine<_Eng, _Kp>& __y); - - template - friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, - const shuffle_order_engine<_Eng, _Kp>& __x); - - template - friend - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, - shuffle_order_engine<_Eng, _Kp>& __x); - - _LIBCPP_INLINE_VISIBILITY - void __init() - { - for (size_t __i = 0; __i < __k; ++__i) - _V_[__i] = __e_(); - _Y_ = __e_(); - } - - _LIBCPP_INLINE_VISIBILITY - result_type __eval(false_type) {return __eval2(integral_constant());} - _LIBCPP_INLINE_VISIBILITY - result_type __eval(true_type) {return __eval(__uratio<__k, _Rp>());} - - _LIBCPP_INLINE_VISIBILITY - result_type __eval2(false_type) {return __eval(__uratio<__k/2, 0x8000000000000000ull>());} - _LIBCPP_INLINE_VISIBILITY - result_type __eval2(true_type) {return __evalf<__k, 0>();} - - template - _LIBCPP_INLINE_VISIBILITY - typename enable_if - < - (__uratio<_Np, _Dp>::num > 0xFFFFFFFFFFFFFFFFull / (_Max - _Min)), - result_type - >::type - __eval(__uratio<_Np, _Dp>) - {return __evalf<__uratio<_Np, _Dp>::num, __uratio<_Np, _Dp>::den>();} - - template - _LIBCPP_INLINE_VISIBILITY - typename enable_if - < - __uratio<_Np, _Dp>::num <= 0xFFFFFFFFFFFFFFFFull / (_Max - _Min), - result_type - >::type - __eval(__uratio<_Np, _Dp>) - { - const size_t __j = static_cast(__uratio<_Np, _Dp>::num * (_Y_ - _Min) - / __uratio<_Np, _Dp>::den); - _Y_ = _V_[__j]; - _V_[__j] = __e_(); - return _Y_; - } - - template - _LIBCPP_INLINE_VISIBILITY - result_type __evalf() - { - const double _Fp = __d == 0 ? - __n / (2. * 0x8000000000000000ull) : - __n / (double)__d; - const size_t __j = static_cast(_Fp * (_Y_ - _Min)); - _Y_ = _V_[__j]; - _V_[__j] = __e_(); - return _Y_; - } -}; - -template - _LIBCPP_CONSTEXPR const size_t shuffle_order_engine<_Engine, __k>::table_size; - -template -bool -operator==( - const shuffle_order_engine<_Eng, _Kp>& __x, - const shuffle_order_engine<_Eng, _Kp>& __y) -{ - return __x._Y_ == __y._Y_ && _VSTD::equal(__x._V_, __x._V_ + _Kp, __y._V_) && - __x.__e_ == __y.__e_; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=( - const shuffle_order_engine<_Eng, _Kp>& __x, - const shuffle_order_engine<_Eng, _Kp>& __y) -{ - return !(__x == __y); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const shuffle_order_engine<_Eng, _Kp>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _Ostream; - __os.flags(_Ostream::dec | _Ostream::left); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - __os << __x.__e_ << __sp << __x._V_[0]; - for (size_t __i = 1; __i < _Kp; ++__i) - __os << __sp << __x._V_[__i]; - return __os << __sp << __x._Y_; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - shuffle_order_engine<_Eng, _Kp>& __x) -{ - typedef typename shuffle_order_engine<_Eng, _Kp>::result_type result_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - _Eng __e; - result_type _Vp[_Kp+1]; - __is >> __e; - for (size_t __i = 0; __i < _Kp+1; ++__i) - __is >> _Vp[__i]; - if (!__is.fail()) - { - __x.__e_ = __e; - for (size_t __i = 0; __i < _Kp; ++__i) - __x._V_[__i] = _Vp[__i]; - __x._Y_ = _Vp[_Kp]; - } - return __is; -} - -typedef shuffle_order_engine knuth_b; - -// random_device - -#if !defined(_LIBCPP_HAS_NO_RANDOM_DEVICE) - -class _LIBCPP_TYPE_VIS random_device -{ -#ifdef _LIBCPP_USING_DEV_RANDOM - int __f_; -#endif // defined(_LIBCPP_USING_DEV_RANDOM) -public: - // types - typedef unsigned result_type; - - // generator characteristics - static _LIBCPP_CONSTEXPR const result_type _Min = 0; - static _LIBCPP_CONSTEXPR const result_type _Max = 0xFFFFFFFFu; - - _LIBCPP_INLINE_VISIBILITY - static _LIBCPP_CONSTEXPR result_type min() { return _Min;} - _LIBCPP_INLINE_VISIBILITY - static _LIBCPP_CONSTEXPR result_type max() { return _Max;} - - // constructors -#ifndef _LIBCPP_CXX03_LANG - random_device() : random_device("/dev/urandom") {} - explicit random_device(const string& __token); -#else - explicit random_device(const string& __token = "/dev/urandom"); -#endif - ~random_device(); - - // generating functions - result_type operator()(); - - // property functions - double entropy() const _NOEXCEPT; - -private: - // no copy functions - random_device(const random_device&); // = delete; - random_device& operator=(const random_device&); // = delete; -}; - -#endif // !_LIBCPP_HAS_NO_RANDOM_DEVICE - -// seed_seq - -class _LIBCPP_TEMPLATE_VIS seed_seq -{ -public: - // types - typedef uint32_t result_type; - -private: - vector __v_; - - template - void init(_InputIterator __first, _InputIterator __last); -public: - // constructors - _LIBCPP_INLINE_VISIBILITY - seed_seq() _NOEXCEPT {} -#ifndef _LIBCPP_CXX03_LANG - template - _LIBCPP_INLINE_VISIBILITY - seed_seq(initializer_list<_Tp> __il) {init(__il.begin(), __il.end());} -#endif // _LIBCPP_CXX03_LANG - - template - _LIBCPP_INLINE_VISIBILITY - seed_seq(_InputIterator __first, _InputIterator __last) - {init(__first, __last);} - - // generating functions - template - void generate(_RandomAccessIterator __first, _RandomAccessIterator __last); - - // property functions - _LIBCPP_INLINE_VISIBILITY - size_t size() const _NOEXCEPT {return __v_.size();} - template - _LIBCPP_INLINE_VISIBILITY - void param(_OutputIterator __dest) const - {_VSTD::copy(__v_.begin(), __v_.end(), __dest);} - -private: - // no copy functions - seed_seq(const seed_seq&); // = delete; - void operator=(const seed_seq&); // = delete; - - _LIBCPP_INLINE_VISIBILITY - static result_type _Tp(result_type __x) {return __x ^ (__x >> 27);} -}; - -template -void -seed_seq::init(_InputIterator __first, _InputIterator __last) -{ - for (_InputIterator __s = __first; __s != __last; ++__s) - __v_.push_back(*__s & 0xFFFFFFFF); -} - -template -void -seed_seq::generate(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - if (__first != __last) - { - _VSTD::fill(__first, __last, 0x8b8b8b8b); - const size_t __n = static_cast(__last - __first); - const size_t __s = __v_.size(); - const size_t __t = (__n >= 623) ? 11 - : (__n >= 68) ? 7 - : (__n >= 39) ? 5 - : (__n >= 7) ? 3 - : (__n - 1) / 2; - const size_t __p = (__n - __t) / 2; - const size_t __q = __p + __t; - const size_t __m = _VSTD::max(__s + 1, __n); - // __k = 0; - { - result_type __r = 1664525 * _Tp(__first[0] ^ __first[__p] - ^ __first[__n - 1]); - __first[__p] += __r; - __r += __s; - __first[__q] += __r; - __first[0] = __r; - } - for (size_t __k = 1; __k <= __s; ++__k) - { - const size_t __kmodn = __k % __n; - const size_t __kpmodn = (__k + __p) % __n; - result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn] - ^ __first[(__k - 1) % __n]); - __first[__kpmodn] += __r; - __r += __kmodn + __v_[__k-1]; - __first[(__k + __q) % __n] += __r; - __first[__kmodn] = __r; - } - for (size_t __k = __s + 1; __k < __m; ++__k) - { - const size_t __kmodn = __k % __n; - const size_t __kpmodn = (__k + __p) % __n; - result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn] - ^ __first[(__k - 1) % __n]); - __first[__kpmodn] += __r; - __r += __kmodn; - __first[(__k + __q) % __n] += __r; - __first[__kmodn] = __r; - } - for (size_t __k = __m; __k < __m + __n; ++__k) - { - const size_t __kmodn = __k % __n; - const size_t __kpmodn = (__k + __p) % __n; - result_type __r = 1566083941 * _Tp(__first[__kmodn] + - __first[__kpmodn] + - __first[(__k - 1) % __n]); - __first[__kpmodn] ^= __r; - __r -= __kmodn; - __first[(__k + __q) % __n] ^= __r; - __first[__kmodn] = __r; - } - } -} - -// generate_canonical - -template -_RealType -generate_canonical(_URNG& __g) -{ - const size_t _Dt = numeric_limits<_RealType>::digits; - const size_t __b = _Dt < __bits ? _Dt : __bits; -#ifdef _LIBCPP_CXX03_LANG - const size_t __logR = __log2::value; -#else - const size_t __logR = __log2::value; -#endif - const size_t __k = __b / __logR + (__b % __logR != 0) + (__b == 0); - const _RealType _Rp = static_cast<_RealType>(_URNG::max() - _URNG::min()) + _RealType(1); - _RealType __base = _Rp; - _RealType _Sp = __g() - _URNG::min(); - for (size_t __i = 1; __i < __k; ++__i, __base *= _Rp) - _Sp += (__g() - _URNG::min()) * __base; - return _Sp / __base; -} - -// uniform_real_distribution - -template -class _LIBCPP_TEMPLATE_VIS uniform_real_distribution -{ -public: - // types - typedef _RealType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - result_type __a_; - result_type __b_; - public: - typedef uniform_real_distribution distribution_type; - - _LIBCPP_INLINE_VISIBILITY - explicit param_type(result_type __a = 0, - result_type __b = 1) - : __a_(__a), __b_(__b) {} - - _LIBCPP_INLINE_VISIBILITY - result_type a() const {return __a_;} - _LIBCPP_INLINE_VISIBILITY - result_type b() const {return __b_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - }; - -private: - param_type __p_; - -public: - // constructors and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - uniform_real_distribution() : uniform_real_distribution(0) {} - explicit uniform_real_distribution(result_type __a, result_type __b = 1) - : __p_(param_type(__a, __b)) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit uniform_real_distribution(result_type __a = 0, result_type __b = 1) - : __p_(param_type(__a, __b)) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit uniform_real_distribution(const param_type& __p) : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template _LIBCPP_INLINE_VISIBILITY result_type operator()(_URNG& __g, const param_type& __p); - - // property functions - _LIBCPP_INLINE_VISIBILITY - result_type a() const {return __p_.a();} - _LIBCPP_INLINE_VISIBILITY - result_type b() const {return __p_.b();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return a();} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return b();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const uniform_real_distribution& __x, - const uniform_real_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const uniform_real_distribution& __x, - const uniform_real_distribution& __y) - {return !(__x == __y);} -}; - -template -template -inline -typename uniform_real_distribution<_RealType>::result_type -uniform_real_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) -{ - return (__p.b() - __p.a()) - * _VSTD::generate_canonical<_RealType, numeric_limits<_RealType>::digits>(__g) - + __p.a(); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const uniform_real_distribution<_RT>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - return __os << __x.a() << __sp << __x.b(); -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - uniform_real_distribution<_RT>& __x) -{ - typedef uniform_real_distribution<_RT> _Eng; - typedef typename _Eng::result_type result_type; - typedef typename _Eng::param_type param_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - result_type __a; - result_type __b; - __is >> __a >> __b; - if (!__is.fail()) - __x.param(param_type(__a, __b)); - return __is; -} - -// bernoulli_distribution - -class _LIBCPP_TEMPLATE_VIS bernoulli_distribution -{ -public: - // types - typedef bool result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - double __p_; - public: - typedef bernoulli_distribution distribution_type; - - _LIBCPP_INLINE_VISIBILITY - explicit param_type(double __p = 0.5) : __p_(__p) {} - - _LIBCPP_INLINE_VISIBILITY - double p() const {return __p_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - }; - -private: - param_type __p_; - -public: - // constructors and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - bernoulli_distribution() : bernoulli_distribution(0.5) {} - _LIBCPP_INLINE_VISIBILITY - explicit bernoulli_distribution(double __p) : __p_(param_type(__p)) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit bernoulli_distribution(double __p = 0.5) : __p_(param_type(__p)) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit bernoulli_distribution(const param_type& __p) : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template _LIBCPP_INLINE_VISIBILITY result_type operator()(_URNG& __g, const param_type& __p); - - // property functions - _LIBCPP_INLINE_VISIBILITY - double p() const {return __p_.p();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return false;} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return true;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const bernoulli_distribution& __x, - const bernoulli_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const bernoulli_distribution& __x, - const bernoulli_distribution& __y) - {return !(__x == __y);} -}; - -template -inline -bernoulli_distribution::result_type -bernoulli_distribution::operator()(_URNG& __g, const param_type& __p) -{ - uniform_real_distribution __gen; - return __gen(__g) < __p.p(); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, const bernoulli_distribution& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - return __os << __x.p(); -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, bernoulli_distribution& __x) -{ - typedef bernoulli_distribution _Eng; - typedef typename _Eng::param_type param_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - double __p; - __is >> __p; - if (!__is.fail()) - __x.param(param_type(__p)); - return __is; -} - -// binomial_distribution - -template -class _LIBCPP_TEMPLATE_VIS binomial_distribution -{ -public: - // types - typedef _IntType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - result_type __t_; - double __p_; - double __pr_; - double __odds_ratio_; - result_type __r0_; - public: - typedef binomial_distribution distribution_type; - - explicit param_type(result_type __t = 1, double __p = 0.5); - - _LIBCPP_INLINE_VISIBILITY - result_type t() const {return __t_;} - _LIBCPP_INLINE_VISIBILITY - double p() const {return __p_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__t_ == __y.__t_ && __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - - friend class binomial_distribution; - }; - -private: - param_type __p_; - -public: - // constructors and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - binomial_distribution() : binomial_distribution(1) {} - _LIBCPP_INLINE_VISIBILITY - explicit binomial_distribution(result_type __t, double __p = 0.5) - : __p_(param_type(__t, __p)) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit binomial_distribution(result_type __t = 1, double __p = 0.5) - : __p_(param_type(__t, __p)) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit binomial_distribution(const param_type& __p) : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template result_type operator()(_URNG& __g, const param_type& __p); - - // property functions - _LIBCPP_INLINE_VISIBILITY - result_type t() const {return __p_.t();} - _LIBCPP_INLINE_VISIBILITY - double p() const {return __p_.p();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return 0;} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return t();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const binomial_distribution& __x, - const binomial_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const binomial_distribution& __x, - const binomial_distribution& __y) - {return !(__x == __y);} -}; - -#ifndef _LIBCPP_MSVCRT_LIKE -extern "C" double lgamma_r(double, int *); -#endif - -inline _LIBCPP_INLINE_VISIBILITY double __libcpp_lgamma(double __d) { -#if defined(_LIBCPP_MSVCRT_LIKE) - return lgamma(__d); -#else - int __sign; - return lgamma_r(__d, &__sign); -#endif -} - -template -binomial_distribution<_IntType>::param_type::param_type(result_type __t, double __p) - : __t_(__t), __p_(__p) -{ - if (0 < __p_ && __p_ < 1) - { - __r0_ = static_cast((__t_ + 1) * __p_); - __pr_ = _VSTD::exp(__libcpp_lgamma(__t_ + 1.) - - __libcpp_lgamma(__r0_ + 1.) - - __libcpp_lgamma(__t_ - __r0_ + 1.) + __r0_ * _VSTD::log(__p_) + - (__t_ - __r0_) * _VSTD::log(1 - __p_)); - __odds_ratio_ = __p_ / (1 - __p_); - } -} - -// Reference: Kemp, C.D. (1986). `A modal method for generating binomial -// variables', Commun. Statist. - Theor. Meth. 15(3), 805-813. -template -template -_IntType -binomial_distribution<_IntType>::operator()(_URNG& __g, const param_type& __pr) -{ - if (__pr.__t_ == 0 || __pr.__p_ == 0) - return 0; - if (__pr.__p_ == 1) - return __pr.__t_; - uniform_real_distribution __gen; - double __u = __gen(__g) - __pr.__pr_; - if (__u < 0) - return __pr.__r0_; - double __pu = __pr.__pr_; - double __pd = __pu; - result_type __ru = __pr.__r0_; - result_type __rd = __ru; - while (true) - { - bool __break = true; - if (__rd >= 1) - { - __pd *= __rd / (__pr.__odds_ratio_ * (__pr.__t_ - __rd + 1)); - __u -= __pd; - __break = false; - if (__u < 0) - return __rd - 1; - } - if ( __rd != 0 ) - --__rd; - ++__ru; - if (__ru <= __pr.__t_) - { - __pu *= (__pr.__t_ - __ru + 1) * __pr.__odds_ratio_ / __ru; - __u -= __pu; - __break = false; - if (__u < 0) - return __ru; - } - if (__break) - return 0; - } -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const binomial_distribution<_IntType>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - return __os << __x.t() << __sp << __x.p(); -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - binomial_distribution<_IntType>& __x) -{ - typedef binomial_distribution<_IntType> _Eng; - typedef typename _Eng::result_type result_type; - typedef typename _Eng::param_type param_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - result_type __t; - double __p; - __is >> __t >> __p; - if (!__is.fail()) - __x.param(param_type(__t, __p)); - return __is; -} - -// exponential_distribution - -template -class _LIBCPP_TEMPLATE_VIS exponential_distribution -{ -public: - // types - typedef _RealType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - result_type __lambda_; - public: - typedef exponential_distribution distribution_type; - - _LIBCPP_INLINE_VISIBILITY - explicit param_type(result_type __lambda = 1) : __lambda_(__lambda) {} - - _LIBCPP_INLINE_VISIBILITY - result_type lambda() const {return __lambda_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__lambda_ == __y.__lambda_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - }; - -private: - param_type __p_; - -public: - // constructors and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - exponential_distribution() : exponential_distribution(1) {} - _LIBCPP_INLINE_VISIBILITY - explicit exponential_distribution(result_type __lambda) - : __p_(param_type(__lambda)) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit exponential_distribution(result_type __lambda = 1) - : __p_(param_type(__lambda)) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit exponential_distribution(const param_type& __p) : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template result_type operator()(_URNG& __g, const param_type& __p); - - // property functions - _LIBCPP_INLINE_VISIBILITY - result_type lambda() const {return __p_.lambda();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return 0;} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return numeric_limits::infinity();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const exponential_distribution& __x, - const exponential_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const exponential_distribution& __x, - const exponential_distribution& __y) - {return !(__x == __y);} -}; - -template -template -_RealType -exponential_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) -{ - return -_VSTD::log - ( - result_type(1) - - _VSTD::generate_canonical::digits>(__g) - ) - / __p.lambda(); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const exponential_distribution<_RealType>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - return __os << __x.lambda(); -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - exponential_distribution<_RealType>& __x) -{ - typedef exponential_distribution<_RealType> _Eng; - typedef typename _Eng::result_type result_type; - typedef typename _Eng::param_type param_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - result_type __lambda; - __is >> __lambda; - if (!__is.fail()) - __x.param(param_type(__lambda)); - return __is; -} - -// normal_distribution - -template -class _LIBCPP_TEMPLATE_VIS normal_distribution -{ -public: - // types - typedef _RealType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - result_type __mean_; - result_type __stddev_; - public: - typedef normal_distribution distribution_type; - - _LIBCPP_INLINE_VISIBILITY - explicit param_type(result_type __mean = 0, result_type __stddev = 1) - : __mean_(__mean), __stddev_(__stddev) {} - - _LIBCPP_INLINE_VISIBILITY - result_type mean() const {return __mean_;} - _LIBCPP_INLINE_VISIBILITY - result_type stddev() const {return __stddev_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__mean_ == __y.__mean_ && __x.__stddev_ == __y.__stddev_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - }; - -private: - param_type __p_; - result_type _V_; - bool _V_hot_; - -public: - // constructors and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - normal_distribution() : normal_distribution(0) {} - _LIBCPP_INLINE_VISIBILITY - explicit normal_distribution(result_type __mean, result_type __stddev = 1) - : __p_(param_type(__mean, __stddev)), _V_hot_(false) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit normal_distribution(result_type __mean = 0, - result_type __stddev = 1) - : __p_(param_type(__mean, __stddev)), _V_hot_(false) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit normal_distribution(const param_type& __p) - : __p_(__p), _V_hot_(false) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {_V_hot_ = false;} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template result_type operator()(_URNG& __g, const param_type& __p); - - // property functions - _LIBCPP_INLINE_VISIBILITY - result_type mean() const {return __p_.mean();} - _LIBCPP_INLINE_VISIBILITY - result_type stddev() const {return __p_.stddev();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return -numeric_limits::infinity();} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return numeric_limits::infinity();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const normal_distribution& __x, - const normal_distribution& __y) - {return __x.__p_ == __y.__p_ && __x._V_hot_ == __y._V_hot_ && - (!__x._V_hot_ || __x._V_ == __y._V_);} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const normal_distribution& __x, - const normal_distribution& __y) - {return !(__x == __y);} - - template - friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, - const normal_distribution<_RT>& __x); - - template - friend - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, - normal_distribution<_RT>& __x); -}; - -template -template -_RealType -normal_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) -{ - result_type _Up; - if (_V_hot_) - { - _V_hot_ = false; - _Up = _V_; - } - else - { - uniform_real_distribution _Uni(-1, 1); - result_type __u; - result_type __v; - result_type __s; - do - { - __u = _Uni(__g); - __v = _Uni(__g); - __s = __u * __u + __v * __v; - } while (__s > 1 || __s == 0); - result_type _Fp = _VSTD::sqrt(-2 * _VSTD::log(__s) / __s); - _V_ = __v * _Fp; - _V_hot_ = true; - _Up = __u * _Fp; - } - return _Up * __p.stddev() + __p.mean(); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const normal_distribution<_RT>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - __os << __x.mean() << __sp << __x.stddev() << __sp << __x._V_hot_; - if (__x._V_hot_) - __os << __sp << __x._V_; - return __os; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - normal_distribution<_RT>& __x) -{ - typedef normal_distribution<_RT> _Eng; - typedef typename _Eng::result_type result_type; - typedef typename _Eng::param_type param_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - result_type __mean; - result_type __stddev; - result_type _Vp = 0; - bool _V_hot = false; - __is >> __mean >> __stddev >> _V_hot; - if (_V_hot) - __is >> _Vp; - if (!__is.fail()) - { - __x.param(param_type(__mean, __stddev)); - __x._V_hot_ = _V_hot; - __x._V_ = _Vp; - } - return __is; -} - -// lognormal_distribution - -template -class _LIBCPP_TEMPLATE_VIS lognormal_distribution -{ -public: - // types - typedef _RealType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - normal_distribution __nd_; - public: - typedef lognormal_distribution distribution_type; - - _LIBCPP_INLINE_VISIBILITY - explicit param_type(result_type __m = 0, result_type __s = 1) - : __nd_(__m, __s) {} - - _LIBCPP_INLINE_VISIBILITY - result_type m() const {return __nd_.mean();} - _LIBCPP_INLINE_VISIBILITY - result_type s() const {return __nd_.stddev();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__nd_ == __y.__nd_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - friend class lognormal_distribution; - - template - friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, - const lognormal_distribution<_RT>& __x); - - template - friend - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, - lognormal_distribution<_RT>& __x); - }; - -private: - param_type __p_; - -public: - // constructor and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - lognormal_distribution() : lognormal_distribution(0) {} - _LIBCPP_INLINE_VISIBILITY - explicit lognormal_distribution(result_type __m, result_type __s = 1) - : __p_(param_type(__m, __s)) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit lognormal_distribution(result_type __m = 0, - result_type __s = 1) - : __p_(param_type(__m, __s)) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit lognormal_distribution(const param_type& __p) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {__p_.__nd_.reset();} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g, const param_type& __p) - {return _VSTD::exp(const_cast&>(__p.__nd_)(__g));} - - // property functions - _LIBCPP_INLINE_VISIBILITY - result_type m() const {return __p_.m();} - _LIBCPP_INLINE_VISIBILITY - result_type s() const {return __p_.s();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return 0;} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return numeric_limits::infinity();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const lognormal_distribution& __x, - const lognormal_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const lognormal_distribution& __x, - const lognormal_distribution& __y) - {return !(__x == __y);} - - template - friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, - const lognormal_distribution<_RT>& __x); - - template - friend - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, - lognormal_distribution<_RT>& __x); -}; - -template -inline _LIBCPP_INLINE_VISIBILITY -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const lognormal_distribution<_RT>& __x) -{ - return __os << __x.__p_.__nd_; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - lognormal_distribution<_RT>& __x) -{ - return __is >> __x.__p_.__nd_; -} - -// poisson_distribution - -template -class _LIBCPP_TEMPLATE_VIS poisson_distribution -{ -public: - // types - typedef _IntType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - double __mean_; - double __s_; - double __d_; - double __l_; - double __omega_; - double __c0_; - double __c1_; - double __c2_; - double __c3_; - double __c_; - - public: - typedef poisson_distribution distribution_type; - - explicit param_type(double __mean = 1.0); - - _LIBCPP_INLINE_VISIBILITY - double mean() const {return __mean_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__mean_ == __y.__mean_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - - friend class poisson_distribution; - }; - -private: - param_type __p_; - -public: - // constructors and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - poisson_distribution() : poisson_distribution(1.0) {} - _LIBCPP_INLINE_VISIBILITY - explicit poisson_distribution(double __mean) - : __p_(__mean) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit poisson_distribution(double __mean = 1.0) - : __p_(__mean) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit poisson_distribution(const param_type& __p) : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template result_type operator()(_URNG& __g, const param_type& __p); - - // property functions - _LIBCPP_INLINE_VISIBILITY - double mean() const {return __p_.mean();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return 0;} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return numeric_limits::max();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const poisson_distribution& __x, - const poisson_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const poisson_distribution& __x, - const poisson_distribution& __y) - {return !(__x == __y);} -}; - -template -poisson_distribution<_IntType>::param_type::param_type(double __mean) - // According to the standard `inf` is a valid input, but it causes the - // distribution to hang, so we replace it with the maximum representable - // mean. - : __mean_(isinf(__mean) ? numeric_limits::max() : __mean) -{ - if (__mean_ < 10) - { - __s_ = 0; - __d_ = 0; - __l_ = _VSTD::exp(-__mean_); - __omega_ = 0; - __c3_ = 0; - __c2_ = 0; - __c1_ = 0; - __c0_ = 0; - __c_ = 0; - } - else - { - __s_ = _VSTD::sqrt(__mean_); - __d_ = 6 * __mean_ * __mean_; - __l_ = _VSTD::trunc(__mean_ - 1.1484); - __omega_ = .3989423 / __s_; - double __b1_ = .4166667E-1 / __mean_; - double __b2_ = .3 * __b1_ * __b1_; - __c3_ = .1428571 * __b1_ * __b2_; - __c2_ = __b2_ - 15. * __c3_; - __c1_ = __b1_ - 6. * __b2_ + 45. * __c3_; - __c0_ = 1. - __b1_ + 3. * __b2_ - 15. * __c3_; - __c_ = .1069 / __mean_; - } -} - -template -template -_IntType -poisson_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr) -{ - double __tx; - uniform_real_distribution __urd; - if (__pr.__mean_ < 10) - { - __tx = 0; - for (double __p = __urd(__urng); __p > __pr.__l_; ++__tx) - __p *= __urd(__urng); - } - else - { - double __difmuk; - double __g = __pr.__mean_ + __pr.__s_ * normal_distribution()(__urng); - double __u; - if (__g > 0) - { - __tx = _VSTD::trunc(__g); - if (__tx >= __pr.__l_) - return _VSTD::__clamp_to_integral(__tx); - __difmuk = __pr.__mean_ - __tx; - __u = __urd(__urng); - if (__pr.__d_ * __u >= __difmuk * __difmuk * __difmuk) - return _VSTD::__clamp_to_integral(__tx); - } - exponential_distribution __edist; - for (bool __using_exp_dist = false; true; __using_exp_dist = true) - { - double __e; - if (__using_exp_dist || __g <= 0) - { - double __t; - do - { - __e = __edist(__urng); - __u = __urd(__urng); - __u += __u - 1; - __t = 1.8 + (__u < 0 ? -__e : __e); - } while (__t <= -.6744); - __tx = _VSTD::trunc(__pr.__mean_ + __pr.__s_ * __t); - __difmuk = __pr.__mean_ - __tx; - __using_exp_dist = true; - } - double __px; - double __py; - if (__tx < 10 && __tx >= 0) - { - const double __fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, - 40320, 362880}; - __px = -__pr.__mean_; - __py = _VSTD::pow(__pr.__mean_, (double)__tx) / __fac[static_cast(__tx)]; - } - else - { - double __del = .8333333E-1 / __tx; - __del -= 4.8 * __del * __del * __del; - double __v = __difmuk / __tx; - if (_VSTD::abs(__v) > 0.25) - __px = __tx * _VSTD::log(1 + __v) - __difmuk - __del; - else - __px = __tx * __v * __v * (((((((.1250060 * __v + -.1384794) * - __v + .1421878) * __v + -.1661269) * __v + .2000118) * - __v + -.2500068) * __v + .3333333) * __v + -.5) - __del; - __py = .3989423 / _VSTD::sqrt(__tx); - } - double __r = (0.5 - __difmuk) / __pr.__s_; - double __r2 = __r * __r; - double __fx = -0.5 * __r2; - double __fy = __pr.__omega_ * (((__pr.__c3_ * __r2 + __pr.__c2_) * - __r2 + __pr.__c1_) * __r2 + __pr.__c0_); - if (__using_exp_dist) - { - if (__pr.__c_ * _VSTD::abs(__u) <= __py * _VSTD::exp(__px + __e) - - __fy * _VSTD::exp(__fx + __e)) - break; - } - else - { - if (__fy - __u * __fy <= __py * _VSTD::exp(__px - __fx)) - break; - } - } - } - return _VSTD::__clamp_to_integral(__tx); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const poisson_distribution<_IntType>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - return __os << __x.mean(); -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - poisson_distribution<_IntType>& __x) -{ - typedef poisson_distribution<_IntType> _Eng; - typedef typename _Eng::param_type param_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - double __mean; - __is >> __mean; - if (!__is.fail()) - __x.param(param_type(__mean)); - return __is; -} - -// weibull_distribution - -template -class _LIBCPP_TEMPLATE_VIS weibull_distribution -{ -public: - // types - typedef _RealType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - result_type __a_; - result_type __b_; - public: - typedef weibull_distribution distribution_type; - - _LIBCPP_INLINE_VISIBILITY - explicit param_type(result_type __a = 1, result_type __b = 1) - : __a_(__a), __b_(__b) {} - - _LIBCPP_INLINE_VISIBILITY - result_type a() const {return __a_;} - _LIBCPP_INLINE_VISIBILITY - result_type b() const {return __b_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - }; - -private: - param_type __p_; - -public: - // constructor and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - weibull_distribution() : weibull_distribution(1) {} - _LIBCPP_INLINE_VISIBILITY - explicit weibull_distribution(result_type __a, result_type __b = 1) - : __p_(param_type(__a, __b)) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit weibull_distribution(result_type __a = 1, result_type __b = 1) - : __p_(param_type(__a, __b)) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit weibull_distribution(const param_type& __p) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g, const param_type& __p) - {return __p.b() * - _VSTD::pow(exponential_distribution()(__g), 1/__p.a());} - - // property functions - _LIBCPP_INLINE_VISIBILITY - result_type a() const {return __p_.a();} - _LIBCPP_INLINE_VISIBILITY - result_type b() const {return __p_.b();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return 0;} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return numeric_limits::infinity();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const weibull_distribution& __x, - const weibull_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const weibull_distribution& __x, - const weibull_distribution& __y) - {return !(__x == __y);} -}; - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const weibull_distribution<_RT>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - __os << __x.a() << __sp << __x.b(); - return __os; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - weibull_distribution<_RT>& __x) -{ - typedef weibull_distribution<_RT> _Eng; - typedef typename _Eng::result_type result_type; - typedef typename _Eng::param_type param_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - result_type __a; - result_type __b; - __is >> __a >> __b; - if (!__is.fail()) - __x.param(param_type(__a, __b)); - return __is; -} - -template -class _LIBCPP_TEMPLATE_VIS extreme_value_distribution -{ -public: - // types - typedef _RealType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - result_type __a_; - result_type __b_; - public: - typedef extreme_value_distribution distribution_type; - - _LIBCPP_INLINE_VISIBILITY - explicit param_type(result_type __a = 0, result_type __b = 1) - : __a_(__a), __b_(__b) {} - - _LIBCPP_INLINE_VISIBILITY - result_type a() const {return __a_;} - _LIBCPP_INLINE_VISIBILITY - result_type b() const {return __b_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - }; - -private: - param_type __p_; - -public: - // constructor and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - extreme_value_distribution() : extreme_value_distribution(0) {} - _LIBCPP_INLINE_VISIBILITY - explicit extreme_value_distribution(result_type __a, result_type __b = 1) - : __p_(param_type(__a, __b)) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit extreme_value_distribution(result_type __a = 0, - result_type __b = 1) - : __p_(param_type(__a, __b)) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit extreme_value_distribution(const param_type& __p) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template result_type operator()(_URNG& __g, const param_type& __p); - - // property functions - _LIBCPP_INLINE_VISIBILITY - result_type a() const {return __p_.a();} - _LIBCPP_INLINE_VISIBILITY - result_type b() const {return __p_.b();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return -numeric_limits::infinity();} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return numeric_limits::infinity();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const extreme_value_distribution& __x, - const extreme_value_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const extreme_value_distribution& __x, - const extreme_value_distribution& __y) - {return !(__x == __y);} -}; - -template -template -_RealType -extreme_value_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) -{ - return __p.a() - __p.b() * - _VSTD::log(-_VSTD::log(1-uniform_real_distribution()(__g))); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const extreme_value_distribution<_RT>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - __os << __x.a() << __sp << __x.b(); - return __os; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - extreme_value_distribution<_RT>& __x) -{ - typedef extreme_value_distribution<_RT> _Eng; - typedef typename _Eng::result_type result_type; - typedef typename _Eng::param_type param_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - result_type __a; - result_type __b; - __is >> __a >> __b; - if (!__is.fail()) - __x.param(param_type(__a, __b)); - return __is; -} - -// gamma_distribution - -template -class _LIBCPP_TEMPLATE_VIS gamma_distribution -{ -public: - // types - typedef _RealType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - result_type __alpha_; - result_type __beta_; - public: - typedef gamma_distribution distribution_type; - - _LIBCPP_INLINE_VISIBILITY - explicit param_type(result_type __alpha = 1, result_type __beta = 1) - : __alpha_(__alpha), __beta_(__beta) {} - - _LIBCPP_INLINE_VISIBILITY - result_type alpha() const {return __alpha_;} - _LIBCPP_INLINE_VISIBILITY - result_type beta() const {return __beta_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__alpha_ == __y.__alpha_ && __x.__beta_ == __y.__beta_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - }; - -private: - param_type __p_; - -public: - // constructors and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - gamma_distribution() : gamma_distribution(1) {} - _LIBCPP_INLINE_VISIBILITY - explicit gamma_distribution(result_type __alpha, result_type __beta = 1) - : __p_(param_type(__alpha, __beta)) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit gamma_distribution(result_type __alpha = 1, - result_type __beta = 1) - : __p_(param_type(__alpha, __beta)) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit gamma_distribution(const param_type& __p) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template result_type operator()(_URNG& __g, const param_type& __p); - - // property functions - _LIBCPP_INLINE_VISIBILITY - result_type alpha() const {return __p_.alpha();} - _LIBCPP_INLINE_VISIBILITY - result_type beta() const {return __p_.beta();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return 0;} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return numeric_limits::infinity();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const gamma_distribution& __x, - const gamma_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const gamma_distribution& __x, - const gamma_distribution& __y) - {return !(__x == __y);} -}; - -template -template -_RealType -gamma_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) -{ - result_type __a = __p.alpha(); - uniform_real_distribution __gen(0, 1); - exponential_distribution __egen; - result_type __x; - if (__a == 1) - __x = __egen(__g); - else if (__a > 1) - { - const result_type __b = __a - 1; - const result_type __c = 3 * __a - result_type(0.75); - while (true) - { - const result_type __u = __gen(__g); - const result_type __v = __gen(__g); - const result_type __w = __u * (1 - __u); - if (__w != 0) - { - const result_type __y = _VSTD::sqrt(__c / __w) * - (__u - result_type(0.5)); - __x = __b + __y; - if (__x >= 0) - { - const result_type __z = 64 * __w * __w * __w * __v * __v; - if (__z <= 1 - 2 * __y * __y / __x) - break; - if (_VSTD::log(__z) <= 2 * (__b * _VSTD::log(__x / __b) - __y)) - break; - } - } - } - } - else // __a < 1 - { - while (true) - { - const result_type __u = __gen(__g); - const result_type __es = __egen(__g); - if (__u <= 1 - __a) - { - __x = _VSTD::pow(__u, 1 / __a); - if (__x <= __es) - break; - } - else - { - const result_type __e = -_VSTD::log((1-__u)/__a); - __x = _VSTD::pow(1 - __a + __a * __e, 1 / __a); - if (__x <= __e + __es) - break; - } - } - } - return __x * __p.beta(); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const gamma_distribution<_RT>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - __os << __x.alpha() << __sp << __x.beta(); - return __os; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - gamma_distribution<_RT>& __x) -{ - typedef gamma_distribution<_RT> _Eng; - typedef typename _Eng::result_type result_type; - typedef typename _Eng::param_type param_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - result_type __alpha; - result_type __beta; - __is >> __alpha >> __beta; - if (!__is.fail()) - __x.param(param_type(__alpha, __beta)); - return __is; -} - -// negative_binomial_distribution - -template -class _LIBCPP_TEMPLATE_VIS negative_binomial_distribution -{ -public: - // types - typedef _IntType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - result_type __k_; - double __p_; - public: - typedef negative_binomial_distribution distribution_type; - - _LIBCPP_INLINE_VISIBILITY - explicit param_type(result_type __k = 1, double __p = 0.5) - : __k_(__k), __p_(__p) {} - - _LIBCPP_INLINE_VISIBILITY - result_type k() const {return __k_;} - _LIBCPP_INLINE_VISIBILITY - double p() const {return __p_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__k_ == __y.__k_ && __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - }; - -private: - param_type __p_; - -public: - // constructor and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - negative_binomial_distribution() : negative_binomial_distribution(1) {} - _LIBCPP_INLINE_VISIBILITY - explicit negative_binomial_distribution(result_type __k, double __p = 0.5) - : __p_(__k, __p) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit negative_binomial_distribution(result_type __k = 1, - double __p = 0.5) - : __p_(__k, __p) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit negative_binomial_distribution(const param_type& __p) : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template result_type operator()(_URNG& __g, const param_type& __p); - - // property functions - _LIBCPP_INLINE_VISIBILITY - result_type k() const {return __p_.k();} - _LIBCPP_INLINE_VISIBILITY - double p() const {return __p_.p();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return 0;} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return numeric_limits::max();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const negative_binomial_distribution& __x, - const negative_binomial_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const negative_binomial_distribution& __x, - const negative_binomial_distribution& __y) - {return !(__x == __y);} -}; - -template -template -_IntType -negative_binomial_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr) -{ - result_type __k = __pr.k(); - double __p = __pr.p(); - if (__k <= 21 * __p) - { - bernoulli_distribution __gen(__p); - result_type __f = 0; - result_type __s = 0; - while (__s < __k) - { - if (__gen(__urng)) - ++__s; - else - ++__f; - } - return __f; - } - return poisson_distribution(gamma_distribution - (__k, (1-__p)/__p)(__urng))(__urng); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const negative_binomial_distribution<_IntType>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - return __os << __x.k() << __sp << __x.p(); -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - negative_binomial_distribution<_IntType>& __x) -{ - typedef negative_binomial_distribution<_IntType> _Eng; - typedef typename _Eng::result_type result_type; - typedef typename _Eng::param_type param_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - result_type __k; - double __p; - __is >> __k >> __p; - if (!__is.fail()) - __x.param(param_type(__k, __p)); - return __is; -} - -// geometric_distribution - -template -class _LIBCPP_TEMPLATE_VIS geometric_distribution -{ -public: - // types - typedef _IntType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - double __p_; - public: - typedef geometric_distribution distribution_type; - - _LIBCPP_INLINE_VISIBILITY - explicit param_type(double __p = 0.5) : __p_(__p) {} - - _LIBCPP_INLINE_VISIBILITY - double p() const {return __p_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - }; - -private: - param_type __p_; - -public: - // constructors and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - geometric_distribution() : geometric_distribution(0.5) {} - _LIBCPP_INLINE_VISIBILITY - explicit geometric_distribution(double __p) - : __p_(__p) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit geometric_distribution(double __p = 0.5) - : __p_(__p) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit geometric_distribution(const param_type& __p) : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g, const param_type& __p) - {return negative_binomial_distribution(1, __p.p())(__g);} - - // property functions - _LIBCPP_INLINE_VISIBILITY - double p() const {return __p_.p();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return 0;} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return numeric_limits::max();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const geometric_distribution& __x, - const geometric_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const geometric_distribution& __x, - const geometric_distribution& __y) - {return !(__x == __y);} -}; - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const geometric_distribution<_IntType>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - return __os << __x.p(); -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - geometric_distribution<_IntType>& __x) -{ - typedef geometric_distribution<_IntType> _Eng; - typedef typename _Eng::param_type param_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - double __p; - __is >> __p; - if (!__is.fail()) - __x.param(param_type(__p)); - return __is; -} - -// chi_squared_distribution - -template -class _LIBCPP_TEMPLATE_VIS chi_squared_distribution -{ -public: - // types - typedef _RealType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - result_type __n_; - public: - typedef chi_squared_distribution distribution_type; - - _LIBCPP_INLINE_VISIBILITY - explicit param_type(result_type __n = 1) : __n_(__n) {} - - _LIBCPP_INLINE_VISIBILITY - result_type n() const {return __n_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__n_ == __y.__n_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - }; - -private: - param_type __p_; - -public: - // constructor and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - chi_squared_distribution() : chi_squared_distribution(1) {} - _LIBCPP_INLINE_VISIBILITY - explicit chi_squared_distribution(result_type __n) - : __p_(param_type(__n)) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit chi_squared_distribution(result_type __n = 1) - : __p_(param_type(__n)) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit chi_squared_distribution(const param_type& __p) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g, const param_type& __p) - {return gamma_distribution(__p.n() / 2, 2)(__g);} - - // property functions - _LIBCPP_INLINE_VISIBILITY - result_type n() const {return __p_.n();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return 0;} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return numeric_limits::infinity();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const chi_squared_distribution& __x, - const chi_squared_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const chi_squared_distribution& __x, - const chi_squared_distribution& __y) - {return !(__x == __y);} -}; - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const chi_squared_distribution<_RT>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - __os << __x.n(); - return __os; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - chi_squared_distribution<_RT>& __x) -{ - typedef chi_squared_distribution<_RT> _Eng; - typedef typename _Eng::result_type result_type; - typedef typename _Eng::param_type param_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - result_type __n; - __is >> __n; - if (!__is.fail()) - __x.param(param_type(__n)); - return __is; -} - -// cauchy_distribution - -template -class _LIBCPP_TEMPLATE_VIS cauchy_distribution -{ -public: - // types - typedef _RealType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - result_type __a_; - result_type __b_; - public: - typedef cauchy_distribution distribution_type; - - _LIBCPP_INLINE_VISIBILITY - explicit param_type(result_type __a = 0, result_type __b = 1) - : __a_(__a), __b_(__b) {} - - _LIBCPP_INLINE_VISIBILITY - result_type a() const {return __a_;} - _LIBCPP_INLINE_VISIBILITY - result_type b() const {return __b_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - }; - -private: - param_type __p_; - -public: - // constructor and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - cauchy_distribution() : cauchy_distribution(0) {} - _LIBCPP_INLINE_VISIBILITY - explicit cauchy_distribution(result_type __a, result_type __b = 1) - : __p_(param_type(__a, __b)) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit cauchy_distribution(result_type __a = 0, result_type __b = 1) - : __p_(param_type(__a, __b)) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit cauchy_distribution(const param_type& __p) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template _LIBCPP_INLINE_VISIBILITY result_type operator()(_URNG& __g, const param_type& __p); - - // property functions - _LIBCPP_INLINE_VISIBILITY - result_type a() const {return __p_.a();} - _LIBCPP_INLINE_VISIBILITY - result_type b() const {return __p_.b();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return -numeric_limits::infinity();} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return numeric_limits::infinity();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const cauchy_distribution& __x, - const cauchy_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const cauchy_distribution& __x, - const cauchy_distribution& __y) - {return !(__x == __y);} -}; - -template -template -inline -_RealType -cauchy_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) -{ - uniform_real_distribution __gen; - // purposefully let tan arg get as close to pi/2 as it wants, tan will return a finite - return __p.a() + __p.b() * _VSTD::tan(3.1415926535897932384626433832795 * __gen(__g)); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const cauchy_distribution<_RT>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - __os << __x.a() << __sp << __x.b(); - return __os; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - cauchy_distribution<_RT>& __x) -{ - typedef cauchy_distribution<_RT> _Eng; - typedef typename _Eng::result_type result_type; - typedef typename _Eng::param_type param_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - result_type __a; - result_type __b; - __is >> __a >> __b; - if (!__is.fail()) - __x.param(param_type(__a, __b)); - return __is; -} - -// fisher_f_distribution - -template -class _LIBCPP_TEMPLATE_VIS fisher_f_distribution -{ -public: - // types - typedef _RealType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - result_type __m_; - result_type __n_; - public: - typedef fisher_f_distribution distribution_type; - - _LIBCPP_INLINE_VISIBILITY - explicit param_type(result_type __m = 1, result_type __n = 1) - : __m_(__m), __n_(__n) {} - - _LIBCPP_INLINE_VISIBILITY - result_type m() const {return __m_;} - _LIBCPP_INLINE_VISIBILITY - result_type n() const {return __n_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__m_ == __y.__m_ && __x.__n_ == __y.__n_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - }; - -private: - param_type __p_; - -public: - // constructor and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - fisher_f_distribution() : fisher_f_distribution(1) {} - _LIBCPP_INLINE_VISIBILITY - explicit fisher_f_distribution(result_type __m, result_type __n = 1) - : __p_(param_type(__m, __n)) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit fisher_f_distribution(result_type __m = 1, result_type __n = 1) - : __p_(param_type(__m, __n)) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit fisher_f_distribution(const param_type& __p) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template result_type operator()(_URNG& __g, const param_type& __p); - - // property functions - _LIBCPP_INLINE_VISIBILITY - result_type m() const {return __p_.m();} - _LIBCPP_INLINE_VISIBILITY - result_type n() const {return __p_.n();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return 0;} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return numeric_limits::infinity();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const fisher_f_distribution& __x, - const fisher_f_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const fisher_f_distribution& __x, - const fisher_f_distribution& __y) - {return !(__x == __y);} -}; - -template -template -_RealType -fisher_f_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) -{ - gamma_distribution __gdm(__p.m() * result_type(.5)); - gamma_distribution __gdn(__p.n() * result_type(.5)); - return __p.n() * __gdm(__g) / (__p.m() * __gdn(__g)); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const fisher_f_distribution<_RT>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - __os << __x.m() << __sp << __x.n(); - return __os; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - fisher_f_distribution<_RT>& __x) -{ - typedef fisher_f_distribution<_RT> _Eng; - typedef typename _Eng::result_type result_type; - typedef typename _Eng::param_type param_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - result_type __m; - result_type __n; - __is >> __m >> __n; - if (!__is.fail()) - __x.param(param_type(__m, __n)); - return __is; -} - -// student_t_distribution - -template -class _LIBCPP_TEMPLATE_VIS student_t_distribution -{ -public: - // types - typedef _RealType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - result_type __n_; - public: - typedef student_t_distribution distribution_type; - - _LIBCPP_INLINE_VISIBILITY - explicit param_type(result_type __n = 1) : __n_(__n) {} - - _LIBCPP_INLINE_VISIBILITY - result_type n() const {return __n_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__n_ == __y.__n_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - }; - -private: - param_type __p_; - normal_distribution __nd_; - -public: - // constructor and reset functions -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - student_t_distribution() : student_t_distribution(1) {} - _LIBCPP_INLINE_VISIBILITY - explicit student_t_distribution(result_type __n) - : __p_(param_type(__n)) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit student_t_distribution(result_type __n = 1) - : __p_(param_type(__n)) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit student_t_distribution(const param_type& __p) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {__nd_.reset();} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template result_type operator()(_URNG& __g, const param_type& __p); - - // property functions - _LIBCPP_INLINE_VISIBILITY - result_type n() const {return __p_.n();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return -numeric_limits::infinity();} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return numeric_limits::infinity();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const student_t_distribution& __x, - const student_t_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const student_t_distribution& __x, - const student_t_distribution& __y) - {return !(__x == __y);} -}; - -template -template -_RealType -student_t_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) -{ - gamma_distribution __gd(__p.n() * .5, 2); - return __nd_(__g) * _VSTD::sqrt(__p.n()/__gd(__g)); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const student_t_distribution<_RT>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - __os << __x.n(); - return __os; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - student_t_distribution<_RT>& __x) -{ - typedef student_t_distribution<_RT> _Eng; - typedef typename _Eng::result_type result_type; - typedef typename _Eng::param_type param_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - result_type __n; - __is >> __n; - if (!__is.fail()) - __x.param(param_type(__n)); - return __is; -} - -// discrete_distribution - -template -class _LIBCPP_TEMPLATE_VIS discrete_distribution -{ -public: - // types - typedef _IntType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - vector __p_; - public: - typedef discrete_distribution distribution_type; - - _LIBCPP_INLINE_VISIBILITY - param_type() {} - template - _LIBCPP_INLINE_VISIBILITY - param_type(_InputIterator __f, _InputIterator __l) - : __p_(__f, __l) {__init();} -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - param_type(initializer_list __wl) - : __p_(__wl.begin(), __wl.end()) {__init();} -#endif // _LIBCPP_CXX03_LANG - template - param_type(size_t __nw, double __xmin, double __xmax, - _UnaryOperation __fw); - - vector probabilities() const; - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - - private: - void __init(); - - friend class discrete_distribution; - - template - friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, - const discrete_distribution<_IT>& __x); - - template - friend - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, - discrete_distribution<_IT>& __x); - }; - -private: - param_type __p_; - -public: - // constructor and reset functions - _LIBCPP_INLINE_VISIBILITY - discrete_distribution() {} - template - _LIBCPP_INLINE_VISIBILITY - discrete_distribution(_InputIterator __f, _InputIterator __l) - : __p_(__f, __l) {} -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - discrete_distribution(initializer_list __wl) - : __p_(__wl) {} -#endif // _LIBCPP_CXX03_LANG - template - _LIBCPP_INLINE_VISIBILITY - discrete_distribution(size_t __nw, double __xmin, double __xmax, - _UnaryOperation __fw) - : __p_(__nw, __xmin, __xmax, __fw) {} - _LIBCPP_INLINE_VISIBILITY - explicit discrete_distribution(const param_type& __p) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template result_type operator()(_URNG& __g, const param_type& __p); - - // property functions - _LIBCPP_INLINE_VISIBILITY - vector probabilities() const {return __p_.probabilities();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return 0;} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return __p_.__p_.size();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const discrete_distribution& __x, - const discrete_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const discrete_distribution& __x, - const discrete_distribution& __y) - {return !(__x == __y);} - - template - friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, - const discrete_distribution<_IT>& __x); - - template - friend - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, - discrete_distribution<_IT>& __x); -}; - -template -template -discrete_distribution<_IntType>::param_type::param_type(size_t __nw, - double __xmin, - double __xmax, - _UnaryOperation __fw) -{ - if (__nw > 1) - { - __p_.reserve(__nw - 1); - double __d = (__xmax - __xmin) / __nw; - double __d2 = __d / 2; - for (size_t __k = 0; __k < __nw; ++__k) - __p_.push_back(__fw(__xmin + __k * __d + __d2)); - __init(); - } -} - -template -void -discrete_distribution<_IntType>::param_type::__init() -{ - if (!__p_.empty()) - { - if (__p_.size() > 1) - { - double __s = _VSTD::accumulate(__p_.begin(), __p_.end(), 0.0); - for (vector::iterator __i = __p_.begin(), __e = __p_.end(); __i < __e; ++__i) - *__i /= __s; - vector __t(__p_.size() - 1); - _VSTD::partial_sum(__p_.begin(), __p_.end() - 1, __t.begin()); - swap(__p_, __t); - } - else - { - __p_.clear(); - __p_.shrink_to_fit(); - } - } -} - -template -vector -discrete_distribution<_IntType>::param_type::probabilities() const -{ - size_t __n = __p_.size(); - vector __p(__n+1); - _VSTD::adjacent_difference(__p_.begin(), __p_.end(), __p.begin()); - if (__n > 0) - __p[__n] = 1 - __p_[__n-1]; - else - __p[0] = 1; - return __p; -} - -template -template -_IntType -discrete_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p) -{ - uniform_real_distribution __gen; - return static_cast<_IntType>( - _VSTD::upper_bound(__p.__p_.begin(), __p.__p_.end(), __gen(__g)) - - __p.__p_.begin()); -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const discrete_distribution<_IT>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - size_t __n = __x.__p_.__p_.size(); - __os << __n; - for (size_t __i = 0; __i < __n; ++__i) - __os << __sp << __x.__p_.__p_[__i]; - return __os; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - discrete_distribution<_IT>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - size_t __n; - __is >> __n; - vector __p(__n); - for (size_t __i = 0; __i < __n; ++__i) - __is >> __p[__i]; - if (!__is.fail()) - swap(__x.__p_.__p_, __p); - return __is; -} - -// piecewise_constant_distribution - -template -class _LIBCPP_TEMPLATE_VIS piecewise_constant_distribution -{ -public: - // types - typedef _RealType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - vector __b_; - vector __densities_; - vector __areas_; - public: - typedef piecewise_constant_distribution distribution_type; - - param_type(); - template - param_type(_InputIteratorB __fB, _InputIteratorB __lB, - _InputIteratorW __fW); -#ifndef _LIBCPP_CXX03_LANG - template - param_type(initializer_list __bl, _UnaryOperation __fw); -#endif // _LIBCPP_CXX03_LANG - template - param_type(size_t __nw, result_type __xmin, result_type __xmax, - _UnaryOperation __fw); - param_type(param_type const&) = default; - param_type & operator=(const param_type& __rhs); - - _LIBCPP_INLINE_VISIBILITY - vector intervals() const {return __b_;} - _LIBCPP_INLINE_VISIBILITY - vector densities() const {return __densities_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__densities_ == __y.__densities_ && __x.__b_ == __y.__b_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - - private: - void __init(); - - friend class piecewise_constant_distribution; - - template - friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, - const piecewise_constant_distribution<_RT>& __x); - - template - friend - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, - piecewise_constant_distribution<_RT>& __x); - }; - -private: - param_type __p_; - -public: - // constructor and reset functions - _LIBCPP_INLINE_VISIBILITY - piecewise_constant_distribution() {} - template - _LIBCPP_INLINE_VISIBILITY - piecewise_constant_distribution(_InputIteratorB __fB, - _InputIteratorB __lB, - _InputIteratorW __fW) - : __p_(__fB, __lB, __fW) {} - -#ifndef _LIBCPP_CXX03_LANG - template - _LIBCPP_INLINE_VISIBILITY - piecewise_constant_distribution(initializer_list __bl, - _UnaryOperation __fw) - : __p_(__bl, __fw) {} -#endif // _LIBCPP_CXX03_LANG - - template - _LIBCPP_INLINE_VISIBILITY - piecewise_constant_distribution(size_t __nw, result_type __xmin, - result_type __xmax, _UnaryOperation __fw) - : __p_(__nw, __xmin, __xmax, __fw) {} - - _LIBCPP_INLINE_VISIBILITY - explicit piecewise_constant_distribution(const param_type& __p) - : __p_(__p) {} - - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template result_type operator()(_URNG& __g, const param_type& __p); - - // property functions - _LIBCPP_INLINE_VISIBILITY - vector intervals() const {return __p_.intervals();} - _LIBCPP_INLINE_VISIBILITY - vector densities() const {return __p_.densities();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return __p_.__b_.front();} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return __p_.__b_.back();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const piecewise_constant_distribution& __x, - const piecewise_constant_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const piecewise_constant_distribution& __x, - const piecewise_constant_distribution& __y) - {return !(__x == __y);} - - template - friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, - const piecewise_constant_distribution<_RT>& __x); - - template - friend - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, - piecewise_constant_distribution<_RT>& __x); -}; - -template -typename piecewise_constant_distribution<_RealType>::param_type & -piecewise_constant_distribution<_RealType>::param_type::operator= - (const param_type& __rhs) -{ -// These can throw - __b_.reserve (__rhs.__b_.size ()); - __densities_.reserve(__rhs.__densities_.size()); - __areas_.reserve (__rhs.__areas_.size()); - -// These can not throw - __b_ = __rhs.__b_; - __densities_ = __rhs.__densities_; - __areas_ = __rhs.__areas_; - return *this; -} - -template -void -piecewise_constant_distribution<_RealType>::param_type::__init() -{ - // __densities_ contains non-normalized areas - result_type __total_area = _VSTD::accumulate(__densities_.begin(), - __densities_.end(), - result_type()); - for (size_t __i = 0; __i < __densities_.size(); ++__i) - __densities_[__i] /= __total_area; - // __densities_ contains normalized areas - __areas_.assign(__densities_.size(), result_type()); - _VSTD::partial_sum(__densities_.begin(), __densities_.end() - 1, - __areas_.begin() + 1); - // __areas_ contains partial sums of normalized areas: [0, __densities_ - 1] - __densities_.back() = 1 - __areas_.back(); // correct round off error - for (size_t __i = 0; __i < __densities_.size(); ++__i) - __densities_[__i] /= (__b_[__i+1] - __b_[__i]); - // __densities_ now contains __densities_ -} - -template -piecewise_constant_distribution<_RealType>::param_type::param_type() - : __b_(2), - __densities_(1, 1.0), - __areas_(1, 0.0) -{ - __b_[1] = 1; -} - -template -template -piecewise_constant_distribution<_RealType>::param_type::param_type( - _InputIteratorB __fB, _InputIteratorB __lB, _InputIteratorW __fW) - : __b_(__fB, __lB) -{ - if (__b_.size() < 2) - { - __b_.resize(2); - __b_[0] = 0; - __b_[1] = 1; - __densities_.assign(1, 1.0); - __areas_.assign(1, 0.0); - } - else - { - __densities_.reserve(__b_.size() - 1); - for (size_t __i = 0; __i < __b_.size() - 1; ++__i, ++__fW) - __densities_.push_back(*__fW); - __init(); - } -} - -#ifndef _LIBCPP_CXX03_LANG - -template -template -piecewise_constant_distribution<_RealType>::param_type::param_type( - initializer_list __bl, _UnaryOperation __fw) - : __b_(__bl.begin(), __bl.end()) -{ - if (__b_.size() < 2) - { - __b_.resize(2); - __b_[0] = 0; - __b_[1] = 1; - __densities_.assign(1, 1.0); - __areas_.assign(1, 0.0); - } - else - { - __densities_.reserve(__b_.size() - 1); - for (size_t __i = 0; __i < __b_.size() - 1; ++__i) - __densities_.push_back(__fw((__b_[__i+1] + __b_[__i])*.5)); - __init(); - } -} - -#endif // _LIBCPP_CXX03_LANG - -template -template -piecewise_constant_distribution<_RealType>::param_type::param_type( - size_t __nw, result_type __xmin, result_type __xmax, _UnaryOperation __fw) - : __b_(__nw == 0 ? 2 : __nw + 1) -{ - size_t __n = __b_.size() - 1; - result_type __d = (__xmax - __xmin) / __n; - __densities_.reserve(__n); - for (size_t __i = 0; __i < __n; ++__i) - { - __b_[__i] = __xmin + __i * __d; - __densities_.push_back(__fw(__b_[__i] + __d*.5)); - } - __b_[__n] = __xmax; - __init(); -} - -template -template -_RealType -piecewise_constant_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) -{ - typedef uniform_real_distribution _Gen; - result_type __u = _Gen()(__g); - ptrdiff_t __k = _VSTD::upper_bound(__p.__areas_.begin(), __p.__areas_.end(), - __u) - __p.__areas_.begin() - 1; - return (__u - __p.__areas_[__k]) / __p.__densities_[__k] + __p.__b_[__k]; -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const piecewise_constant_distribution<_RT>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - size_t __n = __x.__p_.__b_.size(); - __os << __n; - for (size_t __i = 0; __i < __n; ++__i) - __os << __sp << __x.__p_.__b_[__i]; - __n = __x.__p_.__densities_.size(); - __os << __sp << __n; - for (size_t __i = 0; __i < __n; ++__i) - __os << __sp << __x.__p_.__densities_[__i]; - __n = __x.__p_.__areas_.size(); - __os << __sp << __n; - for (size_t __i = 0; __i < __n; ++__i) - __os << __sp << __x.__p_.__areas_[__i]; - return __os; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - piecewise_constant_distribution<_RT>& __x) -{ - typedef piecewise_constant_distribution<_RT> _Eng; - typedef typename _Eng::result_type result_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - size_t __n; - __is >> __n; - vector __b(__n); - for (size_t __i = 0; __i < __n; ++__i) - __is >> __b[__i]; - __is >> __n; - vector __densities(__n); - for (size_t __i = 0; __i < __n; ++__i) - __is >> __densities[__i]; - __is >> __n; - vector __areas(__n); - for (size_t __i = 0; __i < __n; ++__i) - __is >> __areas[__i]; - if (!__is.fail()) - { - swap(__x.__p_.__b_, __b); - swap(__x.__p_.__densities_, __densities); - swap(__x.__p_.__areas_, __areas); - } - return __is; -} - -// piecewise_linear_distribution - -template -class _LIBCPP_TEMPLATE_VIS piecewise_linear_distribution -{ -public: - // types - typedef _RealType result_type; - - class _LIBCPP_TEMPLATE_VIS param_type - { - vector __b_; - vector __densities_; - vector __areas_; - public: - typedef piecewise_linear_distribution distribution_type; - - param_type(); - template - param_type(_InputIteratorB __fB, _InputIteratorB __lB, - _InputIteratorW __fW); -#ifndef _LIBCPP_CXX03_LANG - template - param_type(initializer_list __bl, _UnaryOperation __fw); -#endif // _LIBCPP_CXX03_LANG - template - param_type(size_t __nw, result_type __xmin, result_type __xmax, - _UnaryOperation __fw); - param_type(param_type const&) = default; - param_type & operator=(const param_type& __rhs); - - _LIBCPP_INLINE_VISIBILITY - vector intervals() const {return __b_;} - _LIBCPP_INLINE_VISIBILITY - vector densities() const {return __densities_;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const param_type& __x, const param_type& __y) - {return __x.__densities_ == __y.__densities_ && __x.__b_ == __y.__b_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const param_type& __x, const param_type& __y) - {return !(__x == __y);} - - private: - void __init(); - - friend class piecewise_linear_distribution; - - template - friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, - const piecewise_linear_distribution<_RT>& __x); - - template - friend - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, - piecewise_linear_distribution<_RT>& __x); - }; - -private: - param_type __p_; - -public: - // constructor and reset functions - _LIBCPP_INLINE_VISIBILITY - piecewise_linear_distribution() {} - template - _LIBCPP_INLINE_VISIBILITY - piecewise_linear_distribution(_InputIteratorB __fB, - _InputIteratorB __lB, - _InputIteratorW __fW) - : __p_(__fB, __lB, __fW) {} - -#ifndef _LIBCPP_CXX03_LANG - template - _LIBCPP_INLINE_VISIBILITY - piecewise_linear_distribution(initializer_list __bl, - _UnaryOperation __fw) - : __p_(__bl, __fw) {} -#endif // _LIBCPP_CXX03_LANG - - template - _LIBCPP_INLINE_VISIBILITY - piecewise_linear_distribution(size_t __nw, result_type __xmin, - result_type __xmax, _UnaryOperation __fw) - : __p_(__nw, __xmin, __xmax, __fw) {} - - _LIBCPP_INLINE_VISIBILITY - explicit piecewise_linear_distribution(const param_type& __p) - : __p_(__p) {} - - _LIBCPP_INLINE_VISIBILITY - void reset() {} - - // generating functions - template - _LIBCPP_INLINE_VISIBILITY - result_type operator()(_URNG& __g) - {return (*this)(__g, __p_);} - template result_type operator()(_URNG& __g, const param_type& __p); - - // property functions - _LIBCPP_INLINE_VISIBILITY - vector intervals() const {return __p_.intervals();} - _LIBCPP_INLINE_VISIBILITY - vector densities() const {return __p_.densities();} - - _LIBCPP_INLINE_VISIBILITY - param_type param() const {return __p_;} - _LIBCPP_INLINE_VISIBILITY - void param(const param_type& __p) {__p_ = __p;} - - _LIBCPP_INLINE_VISIBILITY - result_type min() const {return __p_.__b_.front();} - _LIBCPP_INLINE_VISIBILITY - result_type max() const {return __p_.__b_.back();} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const piecewise_linear_distribution& __x, - const piecewise_linear_distribution& __y) - {return __x.__p_ == __y.__p_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const piecewise_linear_distribution& __x, - const piecewise_linear_distribution& __y) - {return !(__x == __y);} - - template - friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, - const piecewise_linear_distribution<_RT>& __x); - - template - friend - basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>& __is, - piecewise_linear_distribution<_RT>& __x); -}; - -template -typename piecewise_linear_distribution<_RealType>::param_type & -piecewise_linear_distribution<_RealType>::param_type::operator= - (const param_type& __rhs) -{ -// These can throw - __b_.reserve (__rhs.__b_.size ()); - __densities_.reserve(__rhs.__densities_.size()); - __areas_.reserve (__rhs.__areas_.size()); - -// These can not throw - __b_ = __rhs.__b_; - __densities_ = __rhs.__densities_; - __areas_ = __rhs.__areas_; - return *this; -} - - -template -void -piecewise_linear_distribution<_RealType>::param_type::__init() -{ - __areas_.assign(__densities_.size() - 1, result_type()); - result_type _Sp = 0; - for (size_t __i = 0; __i < __areas_.size(); ++__i) - { - __areas_[__i] = (__densities_[__i+1] + __densities_[__i]) * - (__b_[__i+1] - __b_[__i]) * .5; - _Sp += __areas_[__i]; - } - for (size_t __i = __areas_.size(); __i > 1;) - { - --__i; - __areas_[__i] = __areas_[__i-1] / _Sp; - } - __areas_[0] = 0; - for (size_t __i = 1; __i < __areas_.size(); ++__i) - __areas_[__i] += __areas_[__i-1]; - for (size_t __i = 0; __i < __densities_.size(); ++__i) - __densities_[__i] /= _Sp; -} - -template -piecewise_linear_distribution<_RealType>::param_type::param_type() - : __b_(2), - __densities_(2, 1.0), - __areas_(1, 0.0) -{ - __b_[1] = 1; -} - -template -template -piecewise_linear_distribution<_RealType>::param_type::param_type( - _InputIteratorB __fB, _InputIteratorB __lB, _InputIteratorW __fW) - : __b_(__fB, __lB) -{ - if (__b_.size() < 2) - { - __b_.resize(2); - __b_[0] = 0; - __b_[1] = 1; - __densities_.assign(2, 1.0); - __areas_.assign(1, 0.0); - } - else - { - __densities_.reserve(__b_.size()); - for (size_t __i = 0; __i < __b_.size(); ++__i, ++__fW) - __densities_.push_back(*__fW); - __init(); - } -} - -#ifndef _LIBCPP_CXX03_LANG - -template -template -piecewise_linear_distribution<_RealType>::param_type::param_type( - initializer_list __bl, _UnaryOperation __fw) - : __b_(__bl.begin(), __bl.end()) -{ - if (__b_.size() < 2) - { - __b_.resize(2); - __b_[0] = 0; - __b_[1] = 1; - __densities_.assign(2, 1.0); - __areas_.assign(1, 0.0); - } - else - { - __densities_.reserve(__b_.size()); - for (size_t __i = 0; __i < __b_.size(); ++__i) - __densities_.push_back(__fw(__b_[__i])); - __init(); - } -} - -#endif // _LIBCPP_CXX03_LANG - -template -template -piecewise_linear_distribution<_RealType>::param_type::param_type( - size_t __nw, result_type __xmin, result_type __xmax, _UnaryOperation __fw) - : __b_(__nw == 0 ? 2 : __nw + 1) -{ - size_t __n = __b_.size() - 1; - result_type __d = (__xmax - __xmin) / __n; - __densities_.reserve(__b_.size()); - for (size_t __i = 0; __i < __n; ++__i) - { - __b_[__i] = __xmin + __i * __d; - __densities_.push_back(__fw(__b_[__i])); - } - __b_[__n] = __xmax; - __densities_.push_back(__fw(__b_[__n])); - __init(); -} - -template -template -_RealType -piecewise_linear_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) -{ - typedef uniform_real_distribution _Gen; - result_type __u = _Gen()(__g); - ptrdiff_t __k = _VSTD::upper_bound(__p.__areas_.begin(), __p.__areas_.end(), - __u) - __p.__areas_.begin() - 1; - __u -= __p.__areas_[__k]; - const result_type __dk = __p.__densities_[__k]; - const result_type __dk1 = __p.__densities_[__k+1]; - const result_type __deltad = __dk1 - __dk; - const result_type __bk = __p.__b_[__k]; - if (__deltad == 0) - return __u / __dk + __bk; - const result_type __bk1 = __p.__b_[__k+1]; - const result_type __deltab = __bk1 - __bk; - return (__bk * __dk1 - __bk1 * __dk + - _VSTD::sqrt(__deltab * (__deltab * __dk * __dk + 2 * __deltad * __u))) / - __deltad; -} - -template -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, - const piecewise_linear_distribution<_RT>& __x) -{ - __save_flags<_CharT, _Traits> __lx(__os); - typedef basic_ostream<_CharT, _Traits> _OStream; - __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | - _OStream::scientific); - _CharT __sp = __os.widen(' '); - __os.fill(__sp); - size_t __n = __x.__p_.__b_.size(); - __os << __n; - for (size_t __i = 0; __i < __n; ++__i) - __os << __sp << __x.__p_.__b_[__i]; - __n = __x.__p_.__densities_.size(); - __os << __sp << __n; - for (size_t __i = 0; __i < __n; ++__i) - __os << __sp << __x.__p_.__densities_[__i]; - __n = __x.__p_.__areas_.size(); - __os << __sp << __n; - for (size_t __i = 0; __i < __n; ++__i) - __os << __sp << __x.__p_.__areas_[__i]; - return __os; -} - -template -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, - piecewise_linear_distribution<_RT>& __x) -{ - typedef piecewise_linear_distribution<_RT> _Eng; - typedef typename _Eng::result_type result_type; - __save_flags<_CharT, _Traits> __lx(__is); - typedef basic_istream<_CharT, _Traits> _Istream; - __is.flags(_Istream::dec | _Istream::skipws); - size_t __n; - __is >> __n; - vector __b(__n); - for (size_t __i = 0; __i < __n; ++__i) - __is >> __b[__i]; - __is >> __n; - vector __densities(__n); - for (size_t __i = 0; __i < __n; ++__i) - __is >> __densities[__i]; - __is >> __n; - vector __areas(__n); - for (size_t __i = 0; __i < __n; ++__i) - __is >> __areas[__i]; - if (!__is.fail()) - { - swap(__x.__p_.__b_, __b); - swap(__x.__p_.__densities_, __densities); - swap(__x.__p_.__areas_, __areas); - } - return __is; -} - -_LIBCPP_END_NAMESPACE_STD - -_LIBCPP_POP_MACROS - #endif // _LIBCPP_RANDOM diff --git a/contrib/llvm-project/libcxx/include/ranges b/contrib/llvm-project/libcxx/include/ranges index 8a99ee64cfc9..dd7decf66fa8 100644 --- a/contrib/llvm-project/libcxx/include/ranges +++ b/contrib/llvm-project/libcxx/include/ranges @@ -36,7 +36,7 @@ namespace std::ranges { inline constexpr bool enable_borrowed_range = false; template - using iterator_t = decltype(ranges::begin(declval())); + using iterator_t = decltype(ranges::begin(declval())); template using sentinel_t = decltype(ranges::end(declval())); template diff --git a/contrib/llvm-project/libcxx/include/string_view b/contrib/llvm-project/libcxx/include/string_view index 0ad7dcce9848..a5f85e88b502 100644 --- a/contrib/llvm-project/libcxx/include/string_view +++ b/contrib/llvm-project/libcxx/include/string_view @@ -87,6 +87,8 @@ namespace std { constexpr basic_string_view(const charT* str, size_type len); template constexpr basic_string_view(It begin, End end); // C++20 + template + constexpr basic_string_view(Range&& r); // C++23 // 7.4, basic_string_view iterator support constexpr const_iterator begin() const noexcept; @@ -171,6 +173,8 @@ namespace std { // basic_string_view deduction guides template basic_string_view(It, End) -> basic_string_view>; // C++20 + template + basic_string_view(Range&&) -> basic_string_view>; // C++23 // 7.11, Hash support template struct hash; @@ -191,12 +195,13 @@ namespace std { */ -#include <__concepts/convertible_to.h> -#include <__concepts/same_as.h> #include <__config> #include <__debug> +#include <__ranges/concepts.h> +#include <__ranges/data.h> #include <__ranges/enable_borrowed_range.h> #include <__ranges/enable_view.h> +#include <__ranges/size.h> #include <__string> #include #include @@ -204,6 +209,7 @@ namespace std { #include #include #include +#include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -282,7 +288,7 @@ public: #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES) template _End> - requires (same_as, _CharT> && !convertible_to<_End, size_type>) + requires (is_same_v, _CharT> && !is_convertible_v<_End, size_type>) constexpr _LIBCPP_HIDE_FROM_ABI basic_string_view(_It __begin, _End __end) : __data(_VSTD::to_address(__begin)), __size(__end - __begin) { @@ -290,6 +296,25 @@ public: } #endif +#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_RANGES) + template + requires ( + !is_same_v, basic_string_view> && + ranges::contiguous_range<_Range> && + ranges::sized_range<_Range> && + is_same_v, _CharT> && + !is_convertible_v<_Range, const _CharT*> && + (!requires(remove_cvref_t<_Range>& d) { + d.operator _VSTD::basic_string_view<_CharT, _Traits>(); + }) && + (!requires { + typename remove_reference_t<_Range>::traits_type; + } || is_same_v::traits_type, _Traits>) + ) + constexpr _LIBCPP_HIDE_FROM_ABI + basic_string_view(_Range&& __r) : __data(ranges::data(__r)), __size(ranges::size(__r)) {} +#endif + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY basic_string_view(const _CharT* __s) : __data(__s), __size(_VSTD::__char_traits_length_checked<_Traits>(__s)) {} @@ -697,6 +722,12 @@ template _End> basic_string_view(_It, _End) -> basic_string_view>; #endif + +#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_RANGES) +template + basic_string_view(_Range) -> basic_string_view>; +#endif + // [string.view.comparison] // operator == template @@ -708,7 +739,9 @@ bool operator==(basic_string_view<_CharT, _Traits> __lhs, return __lhs.compare(__rhs) == 0; } -template +// The dummy default template parameters are used to work around a MSVC issue with mangling, see VSO-409326 for details. +// This applies to the other sufficient overloads below for the other comparison operators. +template _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY bool operator==(basic_string_view<_CharT, _Traits> __lhs, typename common_type >::type __rhs) _NOEXCEPT @@ -717,7 +750,7 @@ bool operator==(basic_string_view<_CharT, _Traits> __lhs, return __lhs.compare(__rhs) == 0; } -template +template _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY bool operator==(typename common_type >::type __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT @@ -737,7 +770,7 @@ bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_Cha return __lhs.compare(__rhs) != 0; } -template +template _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY bool operator!=(basic_string_view<_CharT, _Traits> __lhs, typename common_type >::type __rhs) _NOEXCEPT @@ -747,7 +780,7 @@ bool operator!=(basic_string_view<_CharT, _Traits> __lhs, return __lhs.compare(__rhs) != 0; } -template +template _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY bool operator!=(typename common_type >::type __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT @@ -766,7 +799,7 @@ bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_Char return __lhs.compare(__rhs) < 0; } -template +template _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY bool operator<(basic_string_view<_CharT, _Traits> __lhs, typename common_type >::type __rhs) _NOEXCEPT @@ -774,7 +807,7 @@ bool operator<(basic_string_view<_CharT, _Traits> __lhs, return __lhs.compare(__rhs) < 0; } -template +template _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY bool operator<(typename common_type >::type __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT @@ -791,7 +824,7 @@ bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_Cha return __lhs.compare(__rhs) > 0; } -template +template _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY bool operator>(basic_string_view<_CharT, _Traits> __lhs, typename common_type >::type __rhs) _NOEXCEPT @@ -799,7 +832,7 @@ bool operator>(basic_string_view<_CharT, _Traits> __lhs, return __lhs.compare(__rhs) > 0; } -template +template _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY bool operator>(typename common_type >::type __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT @@ -816,7 +849,7 @@ bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_Cha return __lhs.compare(__rhs) <= 0; } -template +template _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY bool operator<=(basic_string_view<_CharT, _Traits> __lhs, typename common_type >::type __rhs) _NOEXCEPT @@ -824,7 +857,7 @@ bool operator<=(basic_string_view<_CharT, _Traits> __lhs, return __lhs.compare(__rhs) <= 0; } -template +template _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY bool operator<=(typename common_type >::type __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT @@ -842,7 +875,7 @@ bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_Cha } -template +template _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY bool operator>=(basic_string_view<_CharT, _Traits> __lhs, typename common_type >::type __rhs) _NOEXCEPT @@ -850,7 +883,7 @@ bool operator>=(basic_string_view<_CharT, _Traits> __lhs, return __lhs.compare(__rhs) >= 0; } -template +template _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY bool operator>=(typename common_type >::type __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT diff --git a/contrib/llvm-project/libcxx/include/type_traits b/contrib/llvm-project/libcxx/include/type_traits index e9d5e06f36dc..bfb6fcb05134 100644 --- a/contrib/llvm-project/libcxx/include/type_traits +++ b/contrib/llvm-project/libcxx/include/type_traits @@ -1416,9 +1416,7 @@ template using type_identity_t = typename type_identity<_Tp>::type; // is_signed -// Before Clang 10, __is_signed didn't work for floating-point types or enums. -#if __has_keyword(__is_signed) && \ - !(defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1000) +#if __has_keyword(__is_signed) template struct _LIBCPP_TEMPLATE_VIS is_signed : _BoolConstant<__is_signed(_Tp)> { }; diff --git a/contrib/llvm-project/libcxx/include/utility b/contrib/llvm-project/libcxx/include/utility index 2b3c4dfa3f0e..4fa90289a412 100644 --- a/contrib/llvm-project/libcxx/include/utility +++ b/contrib/llvm-project/libcxx/include/utility @@ -227,6 +227,7 @@ template #include <__utility/move.h> #include <__utility/pair.h> #include <__utility/piecewise_construct.h> +#include <__utility/priority_tag.h> #include <__utility/rel_ops.h> #include <__utility/swap.h> #include <__utility/to_underlying.h> diff --git a/contrib/llvm-project/libcxx/include/vector b/contrib/llvm-project/libcxx/include/vector index e41afbaca509..9b0092cfdbd9 100644 --- a/contrib/llvm-project/libcxx/include/vector +++ b/contrib/llvm-project/libcxx/include/vector @@ -350,23 +350,23 @@ class _LIBCPP_TEMPLATE_VIS vector : private __vector_base<_Tp, _Allocator> { private: - typedef __vector_base<_Tp, _Allocator> __base; - typedef allocator<_Tp> __default_allocator_type; + typedef __vector_base<_Tp, _Allocator> __base; + typedef allocator<_Tp> __default_allocator_type; public: - typedef vector __self; - typedef _Tp value_type; - typedef _Allocator allocator_type; - typedef allocator_traits __alloc_traits; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename __allocator_traits::size_type size_type; - typedef typename __alloc_traits::difference_type difference_type; - typedef typename __alloc_traits::pointer pointer; - typedef typename __alloc_traits::const_pointer const_pointer; - typedef __wrap_iter iterator; - typedef __wrap_iter const_iterator; - typedef _VSTD::reverse_iterator reverse_iterator; - typedef _VSTD::reverse_iterator const_reverse_iterator; + typedef vector __self; + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef allocator_traits __alloc_traits; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::difference_type difference_type; + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; + typedef __wrap_iter iterator; + typedef __wrap_iter const_iterator; + typedef _VSTD::reverse_iterator reverse_iterator; + typedef _VSTD::reverse_iterator const_reverse_iterator; static_assert((is_same::value), "Allocator::value_type must be same type as value_type"); @@ -395,7 +395,21 @@ public: explicit vector(size_type __n, const allocator_type& __a); #endif vector(size_type __n, const value_type& __x); - vector(size_type __n, const value_type& __x, const allocator_type& __a); + + template ::value> > + vector(size_type __n, const value_type& __x, const allocator_type& __a) + : __base(__a) + { +#if _LIBCPP_DEBUG_LEVEL == 2 + __get_db()->__insert_c(this); +#endif + if (__n > 0) + { + __vallocate(__n); + __construct_at_end(__n, __x); + } + } + template vector(_InputIterator __first, typename enable_if<__is_cpp17_input_iterator <_InputIterator>::value && @@ -1126,20 +1140,6 @@ vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x) } } -template -vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x, const allocator_type& __a) - : __base(__a) -{ -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__n, __x); - } -} - template template vector<_Tp, _Allocator>::vector(_InputIterator __first, diff --git a/contrib/llvm-project/libcxx/include/version b/contrib/llvm-project/libcxx/include/version index 7c16ac85e430..9322c3b8c05d 100644 --- a/contrib/llvm-project/libcxx/include/version +++ b/contrib/llvm-project/libcxx/include/version @@ -41,6 +41,7 @@ __cpp_lib_bool_constant 201505L __cpp_lib_bounded_array_traits 201902L __cpp_lib_boyer_moore_searcher 201603L __cpp_lib_byte 201603L +__cpp_lib_byteswap 202110L __cpp_lib_char8_t 201811L @@ -72,7 +73,7 @@ __cpp_lib_exchange_function 201304L __cpp_lib_execution 201902L 201603L // C++17 __cpp_lib_filesystem 201703L -__cpp_lib_format 201907L +__cpp_lib_format 202106L __cpp_lib_gcd_lcm 201606L __cpp_lib_generic_associative_lookup 201304L __cpp_lib_generic_unordered_lookup 201811L @@ -300,7 +301,7 @@ __cpp_lib_void_t 201411L # undef __cpp_lib_execution // # define __cpp_lib_execution 201902L # if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) -// # define __cpp_lib_format 201907L +// # define __cpp_lib_format 202106L # endif # define __cpp_lib_generic_unordered_lookup 201811L # define __cpp_lib_int_pow2 202002L @@ -344,6 +345,7 @@ __cpp_lib_void_t 201411L #endif #if _LIBCPP_STD_VER > 20 +# define __cpp_lib_byteswap 202110L # define __cpp_lib_is_scoped_enum 202011L // # define __cpp_lib_stacktrace 202011L // # define __cpp_lib_stdatomic_h 202011L diff --git a/contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h b/contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h index 70092fe4e24d..a2c340e61083 100644 --- a/contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h +++ b/contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h @@ -60,7 +60,7 @@ errc __win_err_to_errc(int err); namespace { -static _LIBCPP_FORMAT_PRINTF(1, 0) string +static _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string format_string_impl(const char* msg, va_list ap) { array buf; @@ -84,7 +84,7 @@ format_string_impl(const char* msg, va_list ap) { return result; } -static _LIBCPP_FORMAT_PRINTF(1, 2) string +static _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string format_string(const char* msg, ...) { string ret; va_list ap; @@ -172,7 +172,7 @@ struct ErrorHandler { _LIBCPP_UNREACHABLE(); } - _LIBCPP_FORMAT_PRINTF(3, 0) + _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 0) void report_impl(const error_code& ec, const char* msg, va_list ap) const { if (ec_) { *ec_ = ec; @@ -191,7 +191,7 @@ struct ErrorHandler { _LIBCPP_UNREACHABLE(); } - _LIBCPP_FORMAT_PRINTF(3, 4) + _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) T report(const error_code& ec, const char* msg, ...) const { va_list ap; va_start(ap, msg); @@ -213,7 +213,7 @@ struct ErrorHandler { return report(make_error_code(err)); } - _LIBCPP_FORMAT_PRINTF(3, 4) + _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) T report(errc const& err, const char* msg, ...) const { va_list ap; va_start(ap, msg); diff --git a/contrib/llvm-project/libunwind/src/Unwind-EHABI.cpp b/contrib/llvm-project/libunwind/src/Unwind-EHABI.cpp index d3577c9f7cf8..5959d2a25fea 100644 --- a/contrib/llvm-project/libunwind/src/Unwind-EHABI.cpp +++ b/contrib/llvm-project/libunwind/src/Unwind-EHABI.cpp @@ -187,9 +187,14 @@ static _Unwind_Reason_Code unwindOneFrame(_Unwind_State state, if (result != _URC_CONTINUE_UNWIND) return result; - if (__unw_step(reinterpret_cast(context)) != UNW_STEP_SUCCESS) + switch (__unw_step(reinterpret_cast(context))) { + case UNW_STEP_SUCCESS: + return _URC_CONTINUE_UNWIND; + case UNW_STEP_END: + return _URC_END_OF_STACK; + default: return _URC_FAILURE; - return _URC_CONTINUE_UNWIND; + } } // Generates mask discriminator for _Unwind_VRS_Pop, e.g. for _UVRSC_CORE / @@ -678,12 +683,13 @@ static _Unwind_Reason_Code unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object, _Unwind_Stop_Fn stop, void *stop_parameter) { + bool endOfStack = false; // See comment at the start of unwind_phase1 regarding VRS integrity. __unw_init_local(cursor, uc); _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_force(ex_ojb=%p)", static_cast(exception_object)); // Walk each frame until we reach where search phase said to stop - while (true) { + while (!endOfStack) { // Update info about this frame. unw_proc_info_t frameInfo; if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { @@ -756,6 +762,14 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, // We may get control back if landing pad calls _Unwind_Resume(). __unw_resume(cursor); break; + case _URC_END_OF_STACK: + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " + "personality returned " + "_URC_END_OF_STACK", + (void *)exception_object); + // Personalty routine did the step and it can't step forward. + endOfStack = true; + break; default: // Personality routine returned an unknown result code. _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " @@ -1133,9 +1147,14 @@ extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception *exception_object, struct _Unwind_Context *context) { unw_cursor_t *cursor = (unw_cursor_t *)context; - if (__unw_step(cursor) != UNW_STEP_SUCCESS) + switch (__unw_step(cursor)) { + case UNW_STEP_SUCCESS: + return _URC_OK; + case UNW_STEP_END: + return _URC_END_OF_STACK; + default: return _URC_FAILURE; - return _URC_OK; + } } #endif // defined(_LIBUNWIND_ARM_EHABI) diff --git a/contrib/llvm-project/lld/COFF/Chunks.cpp b/contrib/llvm-project/lld/COFF/Chunks.cpp index 9f6dbd172509..0bff11f450d1 100644 --- a/contrib/llvm-project/lld/COFF/Chunks.cpp +++ b/contrib/llvm-project/lld/COFF/Chunks.cpp @@ -214,7 +214,8 @@ void SectionChunk::applyRelARM(uint8_t *off, uint16_t type, OutputSection *os, // the page offset from the current instruction to the target. void applyArm64Addr(uint8_t *off, uint64_t s, uint64_t p, int shift) { uint32_t orig = read32le(off); - uint64_t imm = ((orig >> 29) & 0x3) | ((orig >> 3) & 0x1FFFFC); + int64_t imm = + SignExtend64<21>(((orig >> 29) & 0x3) | ((orig >> 3) & 0x1FFFFC)); s += imm; imm = (s >> shift) - (p >> shift); uint32_t immLo = (imm & 0x3) << 29; diff --git a/contrib/llvm-project/lld/COFF/Writer.cpp b/contrib/llvm-project/lld/COFF/Writer.cpp index 600d14034dea..0788f3519f4e 100644 --- a/contrib/llvm-project/lld/COFF/Writer.cpp +++ b/contrib/llvm-project/lld/COFF/Writer.cpp @@ -1211,6 +1211,12 @@ void Writer::createSymbolAndStringTable() { if (!d || d->writtenToSymtab) continue; d->writtenToSymtab = true; + if (auto *dc = dyn_cast_or_null(d)) { + COFFSymbolRef symRef = dc->getCOFFSymbol(); + if (symRef.isSectionDefinition() || + symRef.getStorageClass() == COFF::IMAGE_SYM_CLASS_LABEL) + continue; + } if (Optional sym = createSymbol(d)) outputSymtab.push_back(*sym); diff --git a/contrib/llvm-project/lld/ELF/AArch64ErrataFix.cpp b/contrib/llvm-project/lld/ELF/AArch64ErrataFix.cpp index b9fd4cdbad69..741ff26a7e6c 100644 --- a/contrib/llvm-project/lld/ELF/AArch64ErrataFix.cpp +++ b/contrib/llvm-project/lld/ELF/AArch64ErrataFix.cpp @@ -630,8 +630,8 @@ bool AArch64Err843419Patcher::createFixes() { for (OutputSection *os : outputSections) { if (!(os->flags & SHF_ALLOC) || !(os->flags & SHF_EXECINSTR)) continue; - for (BaseCommand *bc : os->sectionCommands) - if (auto *isd = dyn_cast(bc)) { + for (SectionCommand *cmd : os->commands) + if (auto *isd = dyn_cast(cmd)) { std::vector patches = patchInputSectionDescription(*isd); if (!patches.empty()) { diff --git a/contrib/llvm-project/lld/ELF/ARMErrataFix.cpp b/contrib/llvm-project/lld/ELF/ARMErrataFix.cpp index 77623780ffa5..fe6ec09bd979 100644 --- a/contrib/llvm-project/lld/ELF/ARMErrataFix.cpp +++ b/contrib/llvm-project/lld/ELF/ARMErrataFix.cpp @@ -525,8 +525,8 @@ bool ARMErr657417Patcher::createFixes() { for (OutputSection *os : outputSections) { if (!(os->flags & SHF_ALLOC) || !(os->flags & SHF_EXECINSTR)) continue; - for (BaseCommand *bc : os->sectionCommands) - if (auto *isd = dyn_cast(bc)) { + for (SectionCommand *cmd : os->commands) + if (auto *isd = dyn_cast(cmd)) { std::vector patches = patchInputSectionDescription(*isd); if (!patches.empty()) { diff --git a/contrib/llvm-project/lld/ELF/Arch/ARM.cpp b/contrib/llvm-project/lld/ELF/Arch/ARM.cpp index f2e4a2a14ad6..b7c2eb74757c 100644 --- a/contrib/llvm-project/lld/ELF/Arch/ARM.cpp +++ b/contrib/llvm-project/lld/ELF/Arch/ARM.cpp @@ -140,7 +140,16 @@ RelExpr ARM::getRelExpr(RelType type, const Symbol &s, case R_ARM_THM_MOVT_PREL: return R_PC; case R_ARM_ALU_PC_G0: + case R_ARM_ALU_PC_G0_NC: + case R_ARM_ALU_PC_G1: + case R_ARM_ALU_PC_G1_NC: + case R_ARM_ALU_PC_G2: case R_ARM_LDR_PC_G0: + case R_ARM_LDR_PC_G1: + case R_ARM_LDR_PC_G2: + case R_ARM_LDRS_PC_G0: + case R_ARM_LDRS_PC_G1: + case R_ARM_LDRS_PC_G2: case R_ARM_THM_ALU_PREL_11_0: case R_ARM_THM_PC8: case R_ARM_THM_PC12: @@ -411,56 +420,83 @@ static void stateChangeWarning(uint8_t *loc, RelType relt, const Symbol &s) { } } -// Utility functions taken from ARMAddressingModes.h, only changes are LLD -// coding style. - // Rotate a 32-bit unsigned value right by a specified amt of bits. static uint32_t rotr32(uint32_t val, uint32_t amt) { assert(amt < 32 && "Invalid rotate amount"); return (val >> amt) | (val << ((32 - amt) & 31)); } -// Rotate a 32-bit unsigned value left by a specified amt of bits. -static uint32_t rotl32(uint32_t val, uint32_t amt) { - assert(amt < 32 && "Invalid rotate amount"); - return (val << amt) | (val >> ((32 - amt) & 31)); +static std::pair getRemAndLZForGroup(unsigned group, + uint32_t val) { + uint32_t rem, lz; + do { + lz = llvm::countLeadingZeros(val) & ~1; + rem = val; + if (lz == 32) // implies rem == 0 + break; + val &= 0xffffff >> lz; + } while (group--); + return {rem, lz}; } -// Try to encode a 32-bit unsigned immediate imm with an immediate shifter -// operand, this form is an 8-bit immediate rotated right by an even number of -// bits. We compute the rotate amount to use. If this immediate value cannot be -// handled with a single shifter-op, determine a good rotate amount that will -// take a maximal chunk of bits out of the immediate. -static uint32_t getSOImmValRotate(uint32_t imm) { - // 8-bit (or less) immediates are trivially shifter_operands with a rotate - // of zero. - if ((imm & ~255U) == 0) - return 0; - - // Use CTZ to compute the rotate amount. - unsigned tz = llvm::countTrailingZeros(imm); - - // Rotate amount must be even. Something like 0x200 must be rotated 8 bits, - // not 9. - unsigned rotAmt = tz & ~1; - - // If we can handle this spread, return it. - if ((rotr32(imm, rotAmt) & ~255U) == 0) - return (32 - rotAmt) & 31; // HW rotates right, not left. - - // For values like 0xF000000F, we should ignore the low 6 bits, then - // retry the hunt. - if (imm & 63U) { - unsigned tz2 = countTrailingZeros(imm & ~63U); - unsigned rotAmt2 = tz2 & ~1; - if ((rotr32(imm, rotAmt2) & ~255U) == 0) - return (32 - rotAmt2) & 31; // HW rotates right, not left. +static void encodeAluGroup(uint8_t *loc, const Relocation &rel, uint64_t val, + int group, bool check) { + // ADD/SUB (immediate) add = bit23, sub = bit22 + // immediate field carries is a 12-bit modified immediate, made up of a 4-bit + // even rotate right and an 8-bit immediate. + uint32_t opcode = 0x00800000; + if (val >> 63) { + opcode = 0x00400000; + val = -val; } + uint32_t imm, lz; + std::tie(imm, lz) = getRemAndLZForGroup(group, val); + uint32_t rot = 0; + if (lz < 24) { + imm = rotr32(imm, 24 - lz); + rot = (lz + 8) << 7; + } + if (check && imm > 0xff) + error(getErrorLocation(loc) + "unencodeable immediate " + Twine(val).str() + + " for relocation " + toString(rel.type)); + write32le(loc, (read32le(loc) & 0xff3ff000) | opcode | rot | (imm & 0xff)); +} - // Otherwise, we have no way to cover this span of bits with a single - // shifter_op immediate. Return a chunk of bits that will be useful to - // handle. - return (32 - rotAmt) & 31; // HW rotates right, not left. +static void encodeLdrGroup(uint8_t *loc, const Relocation &rel, uint64_t val, + int group) { + // R_ARM_LDR_PC_Gn is S + A - P, we have ((S + A) | T) - P, if S is a + // function then addr is 0 (modulo 2) and Pa is 0 (modulo 4) so we can clear + // bottom bit to recover S + A - P. + if (rel.sym->isFunc()) + val &= ~0x1; + // LDR (literal) u = bit23 + uint32_t opcode = 0x00800000; + if (val >> 63) { + opcode = 0x0; + val = -val; + } + uint32_t imm = getRemAndLZForGroup(group, val).first; + checkUInt(loc, imm, 12, rel); + write32le(loc, (read32le(loc) & 0xff7ff000) | opcode | imm); +} + +static void encodeLdrsGroup(uint8_t *loc, const Relocation &rel, uint64_t val, + int group) { + // R_ARM_LDRS_PC_Gn is S + A - P, we have ((S + A) | T) - P, if S is a + // function then addr is 0 (modulo 2) and Pa is 0 (modulo 4) so we can clear + // bottom bit to recover S + A - P. + if (rel.sym->isFunc()) + val &= ~0x1; + // LDRD/LDRH/LDRSB/LDRSH (literal) u = bit23 + uint32_t opcode = 0x00800000; + if (val >> 63) { + opcode = 0x0; + val = -val; + } + uint32_t imm = getRemAndLZForGroup(group, val).first; + checkUInt(loc, imm, 8, rel); + write32le(loc, (read32le(loc) & 0xff7ff0f0) | opcode | ((imm & 0xf0) << 4) | + (imm & 0xf)); } void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { @@ -633,45 +669,39 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { ((val << 4) & 0x7000) | // imm3 (val & 0x00ff)); // imm8 break; - case R_ARM_ALU_PC_G0: { - // ADR (literal) add = bit23, sub = bit22 - // literal is a 12-bit modified immediate, made up of a 4-bit even rotate - // right and an 8-bit immediate. The code-sequence here is derived from - // ARMAddressingModes.h in llvm/Target/ARM/MCTargetDesc. In our case we - // want to give an error if we cannot encode the constant. - uint32_t opcode = 0x00800000; - if (val >> 63) { - opcode = 0x00400000; - val = ~val + 1; - } - if ((val & ~255U) != 0) { - uint32_t rotAmt = getSOImmValRotate(val); - // Error if we cannot encode this with a single shift - if (rotr32(~255U, rotAmt) & val) - error(getErrorLocation(loc) + "unencodeable immediate " + - Twine(val).str() + " for relocation " + toString(rel.type)); - val = rotl32(val, rotAmt) | ((rotAmt >> 1) << 8); - } - write32le(loc, (read32le(loc) & 0xff0ff000) | opcode | val); + case R_ARM_ALU_PC_G0: + encodeAluGroup(loc, rel, val, 0, true); break; - } - case R_ARM_LDR_PC_G0: { - // R_ARM_LDR_PC_G0 is S + A - P, we have ((S + A) | T) - P, if S is a - // function then addr is 0 (modulo 2) and Pa is 0 (modulo 4) so we can clear - // bottom bit to recover S + A - P. - if (rel.sym->isFunc()) - val &= ~0x1; - // LDR (literal) u = bit23 - int64_t imm = val; - uint32_t u = 0x00800000; - if (imm < 0) { - imm = -imm; - u = 0; - } - checkUInt(loc, imm, 12, rel); - write32le(loc, (read32le(loc) & 0xff7ff000) | u | imm); + case R_ARM_ALU_PC_G0_NC: + encodeAluGroup(loc, rel, val, 0, false); + break; + case R_ARM_ALU_PC_G1: + encodeAluGroup(loc, rel, val, 1, true); + break; + case R_ARM_ALU_PC_G1_NC: + encodeAluGroup(loc, rel, val, 1, false); + break; + case R_ARM_ALU_PC_G2: + encodeAluGroup(loc, rel, val, 2, true); + break; + case R_ARM_LDR_PC_G0: + encodeLdrGroup(loc, rel, val, 0); + break; + case R_ARM_LDR_PC_G1: + encodeLdrGroup(loc, rel, val, 1); + break; + case R_ARM_LDR_PC_G2: + encodeLdrGroup(loc, rel, val, 2); + break; + case R_ARM_LDRS_PC_G0: + encodeLdrsGroup(loc, rel, val, 0); + break; + case R_ARM_LDRS_PC_G1: + encodeLdrsGroup(loc, rel, val, 1); + break; + case R_ARM_LDRS_PC_G2: + encodeLdrsGroup(loc, rel, val, 2); break; - } case R_ARM_THM_ALU_PREL_11_0: { // ADR encoding T2 (sub), T3 (add) i:imm3:imm8 int64_t imm = val; @@ -816,7 +846,11 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const { ((lo & 0x7000) >> 4) | // imm3 (lo & 0x00ff)); // imm8 } - case R_ARM_ALU_PC_G0: { + case R_ARM_ALU_PC_G0: + case R_ARM_ALU_PC_G0_NC: + case R_ARM_ALU_PC_G1: + case R_ARM_ALU_PC_G1_NC: + case R_ARM_ALU_PC_G2: { // 12-bit immediate is a modified immediate made up of a 4-bit even // right rotation and 8-bit constant. After the rotation the value // is zero-extended. When bit 23 is set the instruction is an add, when @@ -825,13 +859,25 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const { uint32_t val = rotr32(instr & 0xff, ((instr & 0xf00) >> 8) * 2); return (instr & 0x00400000) ? -val : val; } - case R_ARM_LDR_PC_G0: { + case R_ARM_LDR_PC_G0: + case R_ARM_LDR_PC_G1: + case R_ARM_LDR_PC_G2: { // ADR (literal) add = bit23, sub = bit22 // LDR (literal) u = bit23 unsigned imm12 bool u = read32le(buf) & 0x00800000; uint32_t imm12 = read32le(buf) & 0xfff; return u ? imm12 : -imm12; } + case R_ARM_LDRS_PC_G0: + case R_ARM_LDRS_PC_G1: + case R_ARM_LDRS_PC_G2: { + // LDRD/LDRH/LDRSB/LDRSH (literal) u = bit23 unsigned imm8 + uint32_t opcode = read32le(buf); + bool u = opcode & 0x00800000; + uint32_t imm4l = opcode & 0xf; + uint32_t imm4h = (opcode & 0xf00) >> 4; + return u ? (imm4h | imm4l) : -(imm4h | imm4l); + } case R_ARM_THM_ALU_PREL_11_0: { // Thumb2 ADR, which is an alias for a sub or add instruction with an // unsigned immediate. diff --git a/contrib/llvm-project/lld/ELF/Arch/Hexagon.cpp b/contrib/llvm-project/lld/ELF/Arch/Hexagon.cpp index 300ca675519f..c33bd935f363 100644 --- a/contrib/llvm-project/lld/ELF/Arch/Hexagon.cpp +++ b/contrib/llvm-project/lld/ELF/Arch/Hexagon.cpp @@ -146,7 +146,7 @@ RelExpr Hexagon::getRelExpr(RelType type, const Symbol &s, case R_HEX_IE_GOT_32_6_X: case R_HEX_IE_GOT_HI16: case R_HEX_IE_GOT_LO16: - config->hasStaticTlsModel = true; + config->hasTlsIe = true; return R_GOTPLT; case R_HEX_TPREL_11_X: case R_HEX_TPREL_16: diff --git a/contrib/llvm-project/lld/ELF/Arch/RISCV.cpp b/contrib/llvm-project/lld/ELF/Arch/RISCV.cpp index 5ee9e4185f1a..a0ea403e241d 100644 --- a/contrib/llvm-project/lld/ELF/Arch/RISCV.cpp +++ b/contrib/llvm-project/lld/ELF/Arch/RISCV.cpp @@ -261,7 +261,7 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s, case R_RISCV_TLS_GD_HI20: return R_TLSGD_PC; case R_RISCV_TLS_GOT_HI20: - config->hasStaticTlsModel = true; + config->hasTlsIe = true; return R_GOT_PC; case R_RISCV_TPREL_HI20: case R_RISCV_TPREL_LO12_I: diff --git a/contrib/llvm-project/lld/ELF/Arch/X86.cpp b/contrib/llvm-project/lld/ELF/Arch/X86.cpp index 5d34b769e80e..2560dc883257 100644 --- a/contrib/llvm-project/lld/ELF/Arch/X86.cpp +++ b/contrib/llvm-project/lld/ELF/Arch/X86.cpp @@ -78,13 +78,8 @@ int X86::getTlsGdRelaxSkip(RelType type) const { RelExpr X86::getRelExpr(RelType type, const Symbol &s, const uint8_t *loc) const { - // There are 4 different TLS variable models with varying degrees of - // flexibility and performance. LocalExec and InitialExec models are fast but - // less-flexible models. If they are in use, we set DF_STATIC_TLS flag in the - // dynamic section to let runtime know about that. - if (type == R_386_TLS_LE || type == R_386_TLS_LE_32 || type == R_386_TLS_IE || - type == R_386_TLS_GOTIE) - config->hasStaticTlsModel = true; + if (type == R_386_TLS_IE || type == R_386_TLS_GOTIE) + config->hasTlsIe = true; switch (type) { case R_386_8: diff --git a/contrib/llvm-project/lld/ELF/Arch/X86_64.cpp b/contrib/llvm-project/lld/ELF/Arch/X86_64.cpp index 40436752399b..614b5ed59218 100644 --- a/contrib/llvm-project/lld/ELF/Arch/X86_64.cpp +++ b/contrib/llvm-project/lld/ELF/Arch/X86_64.cpp @@ -99,7 +99,11 @@ X86_64::X86_64() { defaultImageBase = 0x200000; } -int X86_64::getTlsGdRelaxSkip(RelType type) const { return 2; } +int X86_64::getTlsGdRelaxSkip(RelType type) const { + // TLSDESC relocations are processed separately. See relaxTlsGdToLe below. + return type == R_X86_64_GOTPC32_TLSDESC || type == R_X86_64_TLSDESC_CALL ? 1 + : 2; +} // Opcodes for the different X86_64 jmp instructions. enum JmpInsnOpcode : uint32_t { @@ -314,7 +318,7 @@ bool X86_64::deleteFallThruJmpInsn(InputSection &is, InputFile *file, RelExpr X86_64::getRelExpr(RelType type, const Symbol &s, const uint8_t *loc) const { if (type == R_X86_64_GOTTPOFF) - config->hasStaticTlsModel = true; + config->hasTlsIe = true; switch (type) { case R_X86_64_8: @@ -443,24 +447,24 @@ void X86_64::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, // The original code used a pc relative relocation and so we have to // compensate for the -4 in had in the addend. write32le(loc + 8, val + 4); - } else { - // Convert - // lea x@tlsgd(%rip), %rax - // call *(%rax) - // to the following two instructions. - assert(rel.type == R_X86_64_GOTPC32_TLSDESC); - if (memcmp(loc - 3, "\x48\x8d\x05", 3)) { - error(getErrorLocation(loc - 3) + "R_X86_64_GOTPC32_TLSDESC must be used " - "in callq *x@tlsdesc(%rip), %rax"); + } else if (rel.type == R_X86_64_GOTPC32_TLSDESC) { + // Convert leaq x@tlsdesc(%rip), %REG to movq $x@tpoff, %REG. + if ((loc[-3] & 0xfb) != 0x48 || loc[-2] != 0x8d || + (loc[-1] & 0xc7) != 0x05) { + errorOrWarn(getErrorLocation(loc - 3) + + "R_X86_64_GOTPC32_TLSDESC must be used " + "in leaq x@tlsdesc(%rip), %REG"); return; } - // movq $x@tpoff(%rip),%rax + loc[-3] = 0x48 | ((loc[-3] >> 2) & 1); loc[-2] = 0xc7; - loc[-1] = 0xc0; + loc[-1] = 0xc0 | ((loc[-1] >> 3) & 7); write32le(loc, val + 4); - // xchg ax,ax - loc[4] = 0x66; - loc[5] = 0x90; + } else { + // Convert call *x@tlsdesc(%REG) to xchg ax, ax. + assert(rel.type == R_X86_64_TLSDESC_CALL); + loc[0] = 0x66; + loc[1] = 0x90; } } @@ -484,23 +488,23 @@ void X86_64::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, // Both code sequences are PC relatives, but since we are moving the // constant forward by 8 bytes we have to subtract the value by 8. write32le(loc + 8, val - 8); - } else { - // Convert - // lea x@tlsgd(%rip), %rax - // call *(%rax) - // to the following two instructions. + } else if (rel.type == R_X86_64_GOTPC32_TLSDESC) { + // Convert leaq x@tlsdesc(%rip), %REG to movq x@gottpoff(%rip), %REG. assert(rel.type == R_X86_64_GOTPC32_TLSDESC); - if (memcmp(loc - 3, "\x48\x8d\x05", 3)) { - error(getErrorLocation(loc - 3) + "R_X86_64_GOTPC32_TLSDESC must be used " - "in callq *x@tlsdesc(%rip), %rax"); + if ((loc[-3] & 0xfb) != 0x48 || loc[-2] != 0x8d || + (loc[-1] & 0xc7) != 0x05) { + errorOrWarn(getErrorLocation(loc - 3) + + "R_X86_64_GOTPC32_TLSDESC must be used " + "in leaq x@tlsdesc(%rip), %REG"); return; } - // movq x@gottpoff(%rip),%rax loc[-2] = 0x8b; write32le(loc, val); - // xchg ax,ax - loc[4] = 0x66; - loc[5] = 0x90; + } else { + // Convert call *x@tlsdesc(%rax) to xchg ax, ax. + assert(rel.type == R_X86_64_TLSDESC_CALL); + loc[0] = 0x66; + loc[1] = 0x90; } } diff --git a/contrib/llvm-project/lld/ELF/Config.h b/contrib/llvm-project/lld/ELF/Config.h index 79c4fe06d7b2..c660a8e67c21 100644 --- a/contrib/llvm-project/lld/ELF/Config.h +++ b/contrib/llvm-project/lld/ELF/Config.h @@ -261,7 +261,7 @@ struct Configuration { UnresolvedPolicy unresolvedSymbols; UnresolvedPolicy unresolvedSymbolsInShlib; Target2Policy target2; - bool Power10Stub; + bool power10Stubs; ARMVFPArgKind armVFPArgs = ARMVFPArgKind::Default; BuildIdKind buildId = BuildIdKind::None; SeparateSegmentKind zSeparate; @@ -309,19 +309,10 @@ struct Configuration { // if that's true.) bool isMips64EL; - // True if we need to set the DF_STATIC_TLS flag to an output file, - // which works as a hint to the dynamic loader that the file contains - // code compiled with the static TLS model. The thread-local variable - // compiled with the static TLS model is faster but less flexible, and - // it may not be loaded using dlopen(). - // - // We set this flag to true when we see a relocation for the static TLS - // model. Once this becomes true, it will never become false. - // - // Since the flag is updated by multi-threaded code, we use std::atomic. - // (Writing to a variable is not considered thread-safe even if the - // variable is boolean and we always set the same value from all threads.) - std::atomic hasStaticTlsModel{false}; + // True if we need to set the DF_STATIC_TLS flag to an output file, which + // works as a hint to the dynamic loader that the shared object contains code + // compiled with the initial-exec TLS model. + bool hasTlsIe = false; // Holds set of ELF header flags for the target. uint32_t eflags = 0; diff --git a/contrib/llvm-project/lld/ELF/Driver.cpp b/contrib/llvm-project/lld/ELF/Driver.cpp index 9fac04558c46..1376e6c2c253 100644 --- a/contrib/llvm-project/lld/ELF/Driver.cpp +++ b/contrib/llvm-project/lld/ELF/Driver.cpp @@ -460,19 +460,21 @@ static bool isKnownZFlag(StringRef s) { s.startswith("start-stop-visibility="); } -// Report an error for an unknown -z option. +// Report a warning for an unknown -z option. static void checkZOptions(opt::InputArgList &args) { for (auto *arg : args.filtered(OPT_z)) if (!isKnownZFlag(arg->getValue())) - error("unknown -z value: " + StringRef(arg->getValue())); + warn("unknown -z value: " + StringRef(arg->getValue())); } void LinkerDriver::linkerMain(ArrayRef argsArr) { ELFOptTable parser; opt::InputArgList args = parser.parse(argsArr.slice(1)); - // Interpret this flag early because error() depends on them. + // Interpret the flags early because error()/warn() depend on them. errorHandler().errorLimit = args::getInteger(args, OPT_error_limit, 20); + errorHandler().fatalWarnings = + args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false); checkZOptions(args); // Handle -help @@ -750,20 +752,6 @@ static OrphanHandlingPolicy getOrphanHandling(opt::InputArgList &args) { return OrphanHandlingPolicy::Place; } -// Parses --power10-stubs= flags, to disable or enable Power 10 -// instructions in stubs. -static bool getP10StubOpt(opt::InputArgList &args) { - - if (args.getLastArgValue(OPT_power10_stubs_eq)== "no") - return false; - - if (!args.hasArg(OPT_power10_stubs_eq) && - args.hasArg(OPT_no_power10_stubs)) - return false; - - return true; -} - // Parse --build-id or --build-id=