diff options
author | Alexander Smirnov <alex@ydb.tech> | 2024-04-23 09:07:41 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2024-04-23 09:07:41 +0000 |
commit | b35b2344f47ddaef21fb74c7f5cad9cd91d3cb45 (patch) | |
tree | e7b382f5c6cce63ce1e160d51ad1aac846ba2905 /library/cpp | |
parent | b3bee3aa6d7c8767695b8917484e6bb488e9c8ca (diff) | |
parent | ae5472d0928c374dc719b154c9dcb2be6e0a0695 (diff) | |
download | ydb-b35b2344f47ddaef21fb74c7f5cad9cd91d3cb45.tar.gz |
Merge branch 'rightlib' into mergelibs-240423-0906
Diffstat (limited to 'library/cpp')
-rw-r--r-- | library/cpp/clang_tidy/arcadia_checks/ascii_compare_ignore_case_check.cpp | 65 | ||||
-rw-r--r-- | library/cpp/clang_tidy/arcadia_checks/ascii_compare_ignore_case_check.h | 21 | ||||
-rw-r--r-- | library/cpp/clang_tidy/arcadia_checks/tidy_module.cpp | 2 | ||||
-rw-r--r-- | library/cpp/clang_tidy/arcadia_checks/usage_restriction_checks.cpp | 4 | ||||
-rw-r--r-- | library/cpp/clang_tidy/arcadia_checks/ya.make | 1 | ||||
-rw-r--r-- | library/cpp/http/io/headers.cpp | 13 | ||||
-rw-r--r-- | library/cpp/monlib/service/format.h | 16 | ||||
-rw-r--r-- | library/cpp/tld/tlds-alpha-by-domain.txt | 2 | ||||
-rw-r--r-- | library/cpp/yt/memory/function_view.h | 32 | ||||
-rw-r--r-- | library/cpp/yt/memory/tls_scratch-inl.h | 28 | ||||
-rw-r--r-- | library/cpp/yt/memory/tls_scratch.h | 20 | ||||
-rw-r--r-- | library/cpp/yt/misc/concepts.h | 49 | ||||
-rw-r--r-- | library/cpp/yt/misc/port.h | 6 |
13 files changed, 212 insertions, 47 deletions
diff --git a/library/cpp/clang_tidy/arcadia_checks/ascii_compare_ignore_case_check.cpp b/library/cpp/clang_tidy/arcadia_checks/ascii_compare_ignore_case_check.cpp new file mode 100644 index 00000000000..c24f40bf0d9 --- /dev/null +++ b/library/cpp/clang_tidy/arcadia_checks/ascii_compare_ignore_case_check.cpp @@ -0,0 +1,65 @@ +#include "ascii_compare_ignore_case_check.h" + +#include <contrib/libs/clang16/include/clang/AST/ASTContext.h> +#include <contrib/libs/clang16/include/clang/ASTMatchers/ASTMatchFinder.h> +#include <contrib/libs/clang16/include/clang/Basic/Diagnostic.h> + + +using namespace clang::ast_matchers; + +namespace clang::tidy::arcadia { + + // This check is based on readability-string-compare. + + static const StringRef DiagMessage = + "do not use 'AsciiCompareIgnoreCase' to test case-insensitive equality " + "of strings; use 'AsciiEqualsIgnoreCase' instead"; + + void AsciiCompareIgnoreCaseCheck::registerMatchers(MatchFinder* finder) { + const auto compareMatcher = callExpr( + callee(functionDecl( + hasName("AsciiCompareIgnoreCase"), + parameterCountIs(2) + )) + ); + + // Case 1: AsciiCompareIgnoreCase(...) is casted (maybe implicitly) to boolean. + finder->addMatcher( + traverse( + TK_AsIs, + // Explicit casts also contain an implicit cast inside + implicitCastExpr(hasImplicitDestinationType(booleanType()), has(compareMatcher)) + .bind("match1")), + this); + + // Case 2: AsciiCompareIgnoreCase == 0 (!= 0) + finder->addMatcher( + binaryOperator( + hasAnyOperatorName("==", "!="), + hasOperands( + compareMatcher.bind("compare"), + integerLiteral(equals(0)).bind("zero"))) + .bind("match2"), + this); + } + + void AsciiCompareIgnoreCaseCheck::check(const MatchFinder::MatchResult& result) { + if (const auto* matched = result.Nodes.getNodeAs<Stmt>("match1")) { + diag(matched->getBeginLoc(), DiagMessage); + } else if (const auto* matched = result.Nodes.getNodeAs<Stmt>("match2")) { + const auto* op = cast<BinaryOperator>(matched); + const auto* compareCall = result.Nodes.getNodeAs<CallExpr>("compare"); + const auto* zero = result.Nodes.getNodeAs<Stmt>("zero"); + + const ASTContext &ctx = *result.Context; + auto diagBuilder = diag(matched->getBeginLoc(), DiagMessage); + if (op->getOpcode() == BinaryOperatorKind::BO_NE) { + diagBuilder << FixItHint::CreateInsertion(compareCall->getCallee()->getBeginLoc(), "!"); + } + diagBuilder << FixItHint::CreateReplacement(compareCall->getCallee()->getSourceRange(), "AsciiEqualsIgnoreCase"); + diagBuilder << FixItHint::CreateRemoval(op->getOperatorLoc()); + diagBuilder << FixItHint::CreateRemoval(zero->getSourceRange()); + } + } + +} // namespace clang::tidy::arcadia diff --git a/library/cpp/clang_tidy/arcadia_checks/ascii_compare_ignore_case_check.h b/library/cpp/clang_tidy/arcadia_checks/ascii_compare_ignore_case_check.h new file mode 100644 index 00000000000..e6da741aa63 --- /dev/null +++ b/library/cpp/clang_tidy/arcadia_checks/ascii_compare_ignore_case_check.h @@ -0,0 +1,21 @@ +#pragma once + +#include <contrib/libs/clang16/tools/extra/clang-tidy/ClangTidyCheck.h> + +namespace clang::tidy::arcadia { + /// Finds uses of AsciiCompareIgnoreCase that can be replaced with AsciiEqualsIgnoreCase. + class AsciiCompareIgnoreCaseCheck : public ClangTidyCheck { + public: + AsciiCompareIgnoreCaseCheck(StringRef name, ClangTidyContext* context) + : ClangTidyCheck(name, context) + {} + + bool isLanguageVersionSupported(const LangOptions& langOpts) const override { + return langOpts.CPlusPlus; + } + + void registerMatchers(ast_matchers::MatchFinder* finder) override; + void check(const ast_matchers::MatchFinder::MatchResult& result) override; + }; + +} // namespace clang::tidy::arcadia diff --git a/library/cpp/clang_tidy/arcadia_checks/tidy_module.cpp b/library/cpp/clang_tidy/arcadia_checks/tidy_module.cpp index 348211949e9..add729d5fb1 100644 --- a/library/cpp/clang_tidy/arcadia_checks/tidy_module.cpp +++ b/library/cpp/clang_tidy/arcadia_checks/tidy_module.cpp @@ -5,6 +5,7 @@ #include "taxi_coroutine_unsafe_check.h" #include "taxi_dangling_config_ref_check.h" +#include "ascii_compare_ignore_case_check.h" #include "usage_restriction_checks.h" using namespace clang::ast_matchers; @@ -21,6 +22,7 @@ namespace clang::tidy::arcadia { // https://st.yandex-team.ru/IGNIETFERRO-1863 CheckFactories.registerCheck<TypeidNameRestrictionCheck>( "arcadia-typeid-name-restriction"); + CheckFactories.registerCheck<AsciiCompareIgnoreCaseCheck>("arcadia-ascii-compare-ignorecase"); } }; diff --git a/library/cpp/clang_tidy/arcadia_checks/usage_restriction_checks.cpp b/library/cpp/clang_tidy/arcadia_checks/usage_restriction_checks.cpp index bc825fa18fe..b4530088076 100644 --- a/library/cpp/clang_tidy/arcadia_checks/usage_restriction_checks.cpp +++ b/library/cpp/clang_tidy/arcadia_checks/usage_restriction_checks.cpp @@ -7,10 +7,10 @@ using namespace clang::ast_matchers; namespace clang::tidy::arcadia { void TypeidNameRestrictionCheck::registerMatchers(MatchFinder* Finder) { Finder->addMatcher(cxxMemberCallExpr(on(expr(hasType(namedDecl(hasName("::std::type_info")))).bind("expr")), - callee(cxxMethodDecl(allOf(hasName("name"), parameterCountIs(0))))), + callee(cxxMethodDecl(hasName("name"), parameterCountIs(0)))), this); Finder->addMatcher(cxxMemberCallExpr(on(expr(hasType(namedDecl(hasName("::std::type_index")))).bind("expr")), - callee(cxxMethodDecl(allOf(hasName("name"), parameterCountIs(0))))), + callee(cxxMethodDecl(hasName("name"), parameterCountIs(0)))), this); } diff --git a/library/cpp/clang_tidy/arcadia_checks/ya.make b/library/cpp/clang_tidy/arcadia_checks/ya.make index 5a38ea6c391..63224e3e50e 100644 --- a/library/cpp/clang_tidy/arcadia_checks/ya.make +++ b/library/cpp/clang_tidy/arcadia_checks/ya.make @@ -10,6 +10,7 @@ NO_COMPILER_WARNINGS() NO_UTIL() SRCS( + ascii_compare_ignore_case_check.cpp taxi_coroutine_unsafe_check.cpp taxi_dangling_config_ref_check.cpp GLOBAL tidy_module.cpp diff --git a/library/cpp/http/io/headers.cpp b/library/cpp/http/io/headers.cpp index 3f3a5a2d07d..9117bc0ba00 100644 --- a/library/cpp/http/io/headers.cpp +++ b/library/cpp/http/io/headers.cpp @@ -12,13 +12,6 @@ static inline TStringBuf Trim(const char* b, const char* e) noexcept { return StripString(TStringBuf(b, e)); } -static inline bool HeaderNameEqual(TStringBuf headerName, TStringBuf expectedName) noexcept { - // Most headers names have distinct sizes. - // Size comparison adds small overhead if all headers have the same size (~4% or lower with size = 4), - // but significantly speeds up the case where sizes are different (~4.5x for expectedName.size() = 4 and headerName.size() = 5) - return headerName.size() == expectedName.size() && AsciiCompareIgnoreCase(headerName, expectedName) == 0; -} - THttpInputHeader::THttpInputHeader(const TStringBuf header) { size_t pos = header.find(':'); @@ -79,7 +72,7 @@ bool THttpHeaders::HasHeader(const TStringBuf header) const { const THttpInputHeader* THttpHeaders::FindHeader(const TStringBuf header) const { for (const auto& hdr : Headers_) { - if (HeaderNameEqual(hdr.Name(), header)) { + if (AsciiEqualsIgnoreCase(hdr.Name(), header)) { return &hdr; } } @@ -88,7 +81,7 @@ const THttpInputHeader* THttpHeaders::FindHeader(const TStringBuf header) const void THttpHeaders::RemoveHeader(const TStringBuf header) { for (auto h = Headers_.begin(); h != Headers_.end(); ++h) { - if (HeaderNameEqual(h->Name(), header)) { + if (AsciiEqualsIgnoreCase(h->Name(), header)) { Headers_.erase(h); return; } @@ -98,7 +91,7 @@ void THttpHeaders::RemoveHeader(const TStringBuf header) { void THttpHeaders::AddOrReplaceHeader(const THttpInputHeader& header) { TStringBuf name = header.Name(); for (auto& hdr : Headers_) { - if (HeaderNameEqual(hdr.Name(), name)) { + if (AsciiEqualsIgnoreCase(hdr.Name(), name)) { hdr = header; return; } diff --git a/library/cpp/monlib/service/format.h b/library/cpp/monlib/service/format.h index 0044b586b19..b95f504c05b 100644 --- a/library/cpp/monlib/service/format.h +++ b/library/cpp/monlib/service/format.h @@ -21,9 +21,11 @@ namespace NMonitoring { auto it = FindIf(std::begin(headers), std::end(headers), [=] (const auto& h) { if constexpr (NPrivate::THasName<std::decay_t<decltype(h)>>::value) { - return AsciiCompareIgnoreCase(h.Name(), TStringBuf("accept-encoding")) == 0; - } else if (isPlainPair) { - return AsciiCompareIgnoreCase(h.first, TStringBuf("accept-encoding")) == 0; + return AsciiEqualsIgnoreCase(h.Name(), TStringBuf("accept-encoding")); + } else if constexpr (isPlainPair) { + return AsciiEqualsIgnoreCase(h.first, TStringBuf("accept-encoding")); + } else { + static_assert(TDependentFalse<decltype(h)>); } }); @@ -66,9 +68,11 @@ namespace NMonitoring { auto it = FindIf(std::begin(headers), std::end(headers), [=] (const auto& h) { if constexpr (NPrivate::THasName<std::decay_t<decltype(h)>>::value) { - return AsciiCompareIgnoreCase(h.Name(), TStringBuf("accept")) == 0; - } else if (isPlainPair) { - return AsciiCompareIgnoreCase(h.first, TStringBuf("accept")) == 0; + return AsciiEqualsIgnoreCase(h.Name(), TStringBuf("accept")); + } else if constexpr (isPlainPair) { + return AsciiEqualsIgnoreCase(h.first, TStringBuf("accept")); + } else { + static_assert(TDependentFalse<decltype(h)>); } }); diff --git a/library/cpp/tld/tlds-alpha-by-domain.txt b/library/cpp/tld/tlds-alpha-by-domain.txt index 3241edfd979..24c895894d1 100644 --- a/library/cpp/tld/tlds-alpha-by-domain.txt +++ b/library/cpp/tld/tlds-alpha-by-domain.txt @@ -1,4 +1,4 @@ -# Version 2024041600, Last Updated Tue Apr 16 07:07:01 2024 UTC +# Version 2024041900, Last Updated Fri Apr 19 07:07:01 2024 UTC AAA AARP ABB diff --git a/library/cpp/yt/memory/function_view.h b/library/cpp/yt/memory/function_view.h index 259238521ff..108fd076ce3 100644 --- a/library/cpp/yt/memory/function_view.h +++ b/library/cpp/yt/memory/function_view.h @@ -1,36 +1,11 @@ #pragma once -#include <concepts> +#include <library/cpp/yt/misc/concepts.h> namespace NYT { //////////////////////////////////////////////////////////////////////////////// -namespace NDetail { - -template <class TSignature> -struct TTypeErasureTraits; - -template <class TResult, bool NoExcept, class... TArgs> -struct TTypeErasureTraits<TResult(TArgs...) noexcept(NoExcept)> -{ - using TSignature = TResult(TArgs...) noexcept(NoExcept); - - // TODO(arkady-e1ppa): Support pointer-to-member-function? - template <class T> - static constexpr bool IsInvocable = NoExcept - ? requires (T obj, TArgs... args) { - { obj(std::forward<TArgs>(args)...) } noexcept -> std::same_as<TResult>; - } - : requires (T obj, TArgs... args) { - { obj(std::forward<TArgs>(args)...) } -> std::same_as<TResult>; - }; -}; - -} // namespace NDetail - -//////////////////////////////////////////////////////////////////////////////// - // Non-owning type-erasure container. /* Example: @@ -75,9 +50,10 @@ class TFunctionView; //////////////////////////////////////////////////////////////////////////////// +// TODO(arkady-e1ppa): Support pointer-to-member-function? template <class T, class TSignature> concept CTypeErasable = - NDetail::TTypeErasureTraits<TSignature>::template IsInvocable<T> && + CInvocable<T, TSignature> && (!std::same_as<T, TFunctionView<TSignature>>); //////////////////////////////////////////////////////////////////////////////// @@ -105,7 +81,7 @@ public: bool IsValid() const noexcept; void Reset() noexcept; - // bool operator==(const TFunctionView& other) const & = default; + bool operator==(const TFunctionView& other) const & = default; private: // NB: Technically, this is UB according to C standard, which diff --git a/library/cpp/yt/memory/tls_scratch-inl.h b/library/cpp/yt/memory/tls_scratch-inl.h new file mode 100644 index 00000000000..32c26d67c08 --- /dev/null +++ b/library/cpp/yt/memory/tls_scratch-inl.h @@ -0,0 +1,28 @@ +#ifndef TLS_SCRATH_INL_H_ +#error "Direct inclusion of this file is not allowed, include tls_scratch.h" +// For the sake of sane code completion. +#include "tls_scratch.h" +#endif + +#include <library/cpp/yt/misc/tls.h> + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +template <class T> +TMutableRange<T> GetTlsScratchBuffer(size_t size) +{ + // This is a workround for std::vector<bool>. + using TBoxed = std::array<T, 1>; + YT_THREAD_LOCAL(std::vector<TBoxed>) tlsVector; + auto& vector = GetTlsRef(tlsVector); + vector.reserve(size); + auto range = TMutableRange(reinterpret_cast<T*>(vector.data()), size); + std::fill(range.begin(), range.end(), T()); + return range; +} + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT diff --git a/library/cpp/yt/memory/tls_scratch.h b/library/cpp/yt/memory/tls_scratch.h new file mode 100644 index 00000000000..20e306f222c --- /dev/null +++ b/library/cpp/yt/memory/tls_scratch.h @@ -0,0 +1,20 @@ +#pragma once + +#include "range.h" + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +//! Returns a temporary buffer (stored on TLS) of a given size. +//! The content is initialized with default values of T before being returned. +template <class T> +TMutableRange<T> GetTlsScratchBuffer(size_t size); + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT + +#define TLS_SCRATH_INL_H_ +#include "tls_scratch-inl.h" +#undef TLS_SCRATH_INL_H_ diff --git a/library/cpp/yt/misc/concepts.h b/library/cpp/yt/misc/concepts.h new file mode 100644 index 00000000000..976c707ffec --- /dev/null +++ b/library/cpp/yt/misc/concepts.h @@ -0,0 +1,49 @@ +#pragma once + +#include <concepts> + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +namespace NDetail { + +template <class T, class TSignature> +struct TIsInvocable; + +template <class T, class TResult, bool NoExcept, class... TArgs> +struct TIsInvocable<T, TResult(TArgs...) noexcept(NoExcept)> +{ +private: + static constexpr bool IsInvocable_ = requires (T&& t, TArgs&&... args) { + { std::forward<T>(t)(std::forward<TArgs>(args)...) } -> std::same_as<TResult>; + }; + + static constexpr bool IsNoThrowInvocable_ = requires (T&& t, TArgs&&... args) { + { std::forward<T>(t)(std::forward<TArgs>(args)...) } noexcept -> std::same_as<TResult>; + }; + +public: + static constexpr bool Value = + IsInvocable_ && + (!NoExcept || IsNoThrowInvocable_); +}; + +} // namespace NDetail + +//////////////////////////////////////////////////////////////////////////////// + +template <class TObject, class TScalar> +concept CScalable = requires (TObject object, TScalar scalar) +{ + { object * scalar } -> std::same_as<TObject>; +}; + +//////////////////////////////////////////////////////////////////////////////// + +template <class T, class TSignature> +concept CInvocable = NDetail::TIsInvocable<T, TSignature>::Value; + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT diff --git a/library/cpp/yt/misc/port.h b/library/cpp/yt/misc/port.h index 7cfb8257087..e30e163a59f 100644 --- a/library/cpp/yt/misc/port.h +++ b/library/cpp/yt/misc/port.h @@ -69,3 +69,9 @@ #else #error Unsupported compiler #endif + +#if defined(_unix_) + #define NO_UNIQUE_ADDRESS [[no_unique_address]] +#else + #define NO_UNIQUE_ADDRESS +#endif |