aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp
diff options
context:
space:
mode:
authorAlexander Smirnov <alex@ydb.tech>2024-04-23 09:07:41 +0000
committerAlexander Smirnov <alex@ydb.tech>2024-04-23 09:07:41 +0000
commitb35b2344f47ddaef21fb74c7f5cad9cd91d3cb45 (patch)
treee7b382f5c6cce63ce1e160d51ad1aac846ba2905 /library/cpp
parentb3bee3aa6d7c8767695b8917484e6bb488e9c8ca (diff)
parentae5472d0928c374dc719b154c9dcb2be6e0a0695 (diff)
downloadydb-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.cpp65
-rw-r--r--library/cpp/clang_tidy/arcadia_checks/ascii_compare_ignore_case_check.h21
-rw-r--r--library/cpp/clang_tidy/arcadia_checks/tidy_module.cpp2
-rw-r--r--library/cpp/clang_tidy/arcadia_checks/usage_restriction_checks.cpp4
-rw-r--r--library/cpp/clang_tidy/arcadia_checks/ya.make1
-rw-r--r--library/cpp/http/io/headers.cpp13
-rw-r--r--library/cpp/monlib/service/format.h16
-rw-r--r--library/cpp/tld/tlds-alpha-by-domain.txt2
-rw-r--r--library/cpp/yt/memory/function_view.h32
-rw-r--r--library/cpp/yt/memory/tls_scratch-inl.h28
-rw-r--r--library/cpp/yt/memory/tls_scratch.h20
-rw-r--r--library/cpp/yt/misc/concepts.h49
-rw-r--r--library/cpp/yt/misc/port.h6
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