diff options
author | Alexander Smirnov <alex@ydb.tech> | 2024-04-08 08:20:18 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2024-04-08 08:20:18 +0000 |
commit | 40921060b649610421ba31cbe78cd6be2e222929 (patch) | |
tree | a0d3eaf0995dd00e7970e4a54a8fb11ca311c21f /library/cpp | |
parent | 3fa95b9777601584da35d5925d7908f283f671a9 (diff) | |
parent | 72eeab5172756159750eef875745e2a6f5b0004f (diff) | |
download | ydb-40921060b649610421ba31cbe78cd6be2e222929.tar.gz |
Merge branch 'rightlib' into mergelibs-240408-0819
Diffstat (limited to 'library/cpp')
-rw-r--r-- | library/cpp/http/io/chunk.h | 4 | ||||
-rw-r--r-- | library/cpp/tld/tlds-alpha-by-domain.txt | 2 | ||||
-rw-r--r-- | library/cpp/yt/misc/function_view-inl.h | 71 | ||||
-rw-r--r-- | library/cpp/yt/misc/function_view.h | 139 |
4 files changed, 214 insertions, 2 deletions
diff --git a/library/cpp/http/io/chunk.h b/library/cpp/http/io/chunk.h index 88d89fafda2..6d477b04a9b 100644 --- a/library/cpp/http/io/chunk.h +++ b/library/cpp/http/io/chunk.h @@ -35,8 +35,10 @@ public: TChunkedOutput(IOutputStream* slave); ~TChunkedOutput() override; -private: +protected: void DoWrite(const void* buf, size_t len) override; + +private: void DoFlush() override; void DoFinish() override; diff --git a/library/cpp/tld/tlds-alpha-by-domain.txt b/library/cpp/tld/tlds-alpha-by-domain.txt index 374cf501922..eb3b65c176b 100644 --- a/library/cpp/tld/tlds-alpha-by-domain.txt +++ b/library/cpp/tld/tlds-alpha-by-domain.txt @@ -1,4 +1,4 @@ -# Version 2024033102, Last Updated Mon Apr 1 07:07:01 2024 UTC +# Version 2024040700, Last Updated Sun Apr 7 07:07:01 2024 UTC AAA AARP ABB diff --git a/library/cpp/yt/misc/function_view-inl.h b/library/cpp/yt/misc/function_view-inl.h new file mode 100644 index 00000000000..ececfdf3357 --- /dev/null +++ b/library/cpp/yt/misc/function_view-inl.h @@ -0,0 +1,71 @@ +#pragma once +#ifndef FUNCTION_VIEW_INL_H_ +#error "Direct inclusion of this file is not allowed, include function_view.h" +// For the sake of sane code completion. +#include "function_view.h" +#endif + +#include <library/cpp/yt/assert/assert.h> + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +template <class TResult, bool NoExcept, class... TArgs> +template <CTypeErasable<TResult(TArgs...) noexcept(NoExcept)> TConcrete> +TFunctionView<TResult(TArgs...) noexcept(NoExcept)>::TFunctionView(TConcrete& concreteRef) noexcept + : TFunctionView(&concreteRef) +{ } + +template <class TResult, bool NoExcept, class... TArgs> +template <CTypeErasable<TResult(TArgs...) noexcept(NoExcept)> TConcrete> +TFunctionView<TResult(TArgs...) noexcept(NoExcept)>::TFunctionView(TConcrete* concretePtr) noexcept +{ + Ptr_ = reinterpret_cast<void*>(concretePtr); + Invoke_ = &TFunctionView::ConcreteInvoke<TConcrete>; +} + +template <class TResult, bool NoExcept, class... TArgs> +TFunctionView<TResult(TArgs...) noexcept(NoExcept)> +TFunctionView<TResult(TArgs...) noexcept(NoExcept)>::Release() noexcept +{ + auto copy = *this; + Reset(); + return copy; +} + +template <class TResult, bool NoExcept, class... TArgs> +TResult TFunctionView<TResult(TArgs...) noexcept(NoExcept)>::operator()(TArgs... args) noexcept(NoExcept) +{ + YT_VERIFY(Ptr_); + return Invoke_(std::forward<TArgs>(args)..., Ptr_); +} + +template <class TResult, bool NoExcept, class... TArgs> +template <class TConcrete> +TResult TFunctionView<TResult(TArgs...) noexcept(NoExcept)>::ConcreteInvoke(TArgs... args, TErasedPtr ptr) noexcept(NoExcept) +{ + return (*reinterpret_cast<TConcrete*>(ptr))(std::forward<TArgs>(args)...); +} + +template <class TResult, bool NoExcept, class... TArgs> +TFunctionView<TResult(TArgs...) noexcept(NoExcept)>::operator bool() const noexcept +{ + return IsValid(); +} + +template <class TResult, bool NoExcept, class... TArgs> +bool TFunctionView<TResult(TArgs...) noexcept(NoExcept)>::IsValid() const noexcept +{ + return Ptr_ != nullptr; +} + +template <class TResult, bool NoExcept, class... TArgs> +void TFunctionView<TResult(TArgs...) noexcept(NoExcept)>::Reset() noexcept +{ + Ptr_ = nullptr; +} + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT diff --git a/library/cpp/yt/misc/function_view.h b/library/cpp/yt/misc/function_view.h new file mode 100644 index 00000000000..259238521ff --- /dev/null +++ b/library/cpp/yt/misc/function_view.h @@ -0,0 +1,139 @@ +#pragma once + +#include <concepts> + +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: + + template <class T> + class TSerializedObject + { + public: + explicit TSerializedObject(T value) + : Object_(value) + { } + + void Lock(TFunctionView<void(const T&)> callback) + { + auto guard = Guard(SpinLock_); + callback(Object_); + } + + private: + TSpinLock SpinLock_; + T Object_; + }; + + int main() + { + TSerializedObject<int> object(42); + + // object.Lock([] (const int& value) { + // fmt::println("Value is {}", value); + // }); + // ^ CE -- cannot pass rvalue. + + auto callback = [] (const int& value) { + fmt::println("Value is {}", value); + }; + + object.Lock(callback); // <- prints "Value is 42". + } +*/ +template <class TSignature> +class TFunctionView; + +//////////////////////////////////////////////////////////////////////////////// + +template <class T, class TSignature> +concept CTypeErasable = + NDetail::TTypeErasureTraits<TSignature>::template IsInvocable<T> && + (!std::same_as<T, TFunctionView<TSignature>>); + +//////////////////////////////////////////////////////////////////////////////// + +template <class TResult, bool NoExcept, class... TArgs> +class TFunctionView<TResult(TArgs...) noexcept(NoExcept)> +{ +public: + using TSignature = TResult(TArgs...) noexcept(NoExcept); + + TFunctionView() = default; + + template <CTypeErasable<TSignature> TConcrete> + TFunctionView(TConcrete& concreteRef) noexcept; + + template <CTypeErasable<TSignature> TConcrete> + TFunctionView(TConcrete* concretePtr) noexcept; + + TResult operator()(TArgs... args) noexcept(NoExcept); + + explicit operator bool() const noexcept; + + TFunctionView Release() noexcept; + + bool IsValid() const noexcept; + void Reset() noexcept; + + // bool operator==(const TFunctionView& other) const & = default; + +private: + // NB: Technically, this is UB according to C standard, which + // was not changed for C++ standard. + // This is so because it is allowed to have + // function pointers to be modelled by entities + // different from object pointers. + // No reasonable system architecture (e.g. x86 or ARM + // or any other POSIX compliant one) does this. + // No reasonable compiler (clang/gcc) does anything with this. + // Accounting for such requirement would cause this class + // to have std::variant-like storage which would make this class + // weight more. Thus, we have decided to keep it this way, + // since we are safe on x86 or ARM + clang. + using TErasedPtr = void*; + using TErasedInvoke = TResult(*)(TArgs..., TErasedPtr); + + TErasedPtr Ptr_ = nullptr; + TErasedInvoke Invoke_ = nullptr; + + template <class TConcrete> + static TResult ConcreteInvoke(TArgs... args, TErasedPtr ptr) noexcept(NoExcept); +}; + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT + +#define FUNCTION_VIEW_INL_H_ +#include "function_view-inl.h" +#undef FUNCTION_VIEW_INL_H_ |