diff options
| author | arkady-e1ppa <[email protected]> | 2023-12-06 13:44:55 +0300 |
|---|---|---|
| committer | arkady-e1ppa <[email protected]> | 2023-12-06 14:42:52 +0300 |
| commit | 10b68f0ea44b5e614b91d59a5dd5bb5a878f5eac (patch) | |
| tree | 9571a47cd5426c3b9042cf3e350d05f41bd72266 /library/cpp/yt | |
| parent | bfb11ee270b827ddd066a35ee4aa96c389c87603 (diff) | |
YT-20547: TIncarnationId is strongly typed
First commit
Diffstat (limited to 'library/cpp/yt')
| -rw-r--r-- | library/cpp/yt/misc/wrapper_traits-inl.h | 28 | ||||
| -rw-r--r-- | library/cpp/yt/misc/wrapper_traits.h | 14 |
2 files changed, 41 insertions, 1 deletions
diff --git a/library/cpp/yt/misc/wrapper_traits-inl.h b/library/cpp/yt/misc/wrapper_traits-inl.h index 88d1af5945d..7ab7699641e 100644 --- a/library/cpp/yt/misc/wrapper_traits-inl.h +++ b/library/cpp/yt/misc/wrapper_traits-inl.h @@ -78,6 +78,32 @@ constexpr bool TWrapperTraits<T>::RecursiveHasValue(const T& wrapper) noexcept } } +template <class T> + requires std::is_object_v<T> +template <class U> +constexpr T TWrapperTraits<T>::Wrap(U&& unwrapped) noexcept +{ + static_assert(std::same_as<std::remove_cvref_t<U>, TUnwrapped>); + + return T(std::forward<U>(unwrapped)); +} + +template <class T> + requires std::is_object_v<T> +template <class U> +constexpr T TWrapperTraits<T>::RecursiveWrap(U&& unwrapped) noexcept +{ + using TTraits = TWrapperTraits<T>; + using TInnerTraits = TWrapperTraits<typename TTraits::TUnwrapped>; + + if constexpr (CNonTrivialWrapper<TUnwrapped>) { + return TTraits::Wrap(TInnerTraits::RecursiveWrap(std::forward<U>(unwrapped))); + } else { + //! U == TUnwrapped. + return TTraits::Wrap(std::forward<U>(unwrapped)); + } +} + //////////////////////////////////////////////////////////////////////////////// //! Some standard library specializations @@ -98,7 +124,7 @@ struct TBasicWrapperTraits<std::optional<T>> template <class U> requires std::same_as<std::remove_cvref_t<U>, std::optional<T>> - static decltype(auto) Unwrap(U&& optional) + static constexpr decltype(auto) Unwrap(U&& optional) { return *std::forward<U>(optional); } diff --git a/library/cpp/yt/misc/wrapper_traits.h b/library/cpp/yt/misc/wrapper_traits.h index 61a97b8ea44..8a6d5814199 100644 --- a/library/cpp/yt/misc/wrapper_traits.h +++ b/library/cpp/yt/misc/wrapper_traits.h @@ -1,5 +1,6 @@ #pragma once +#include <concepts> #include <utility> namespace NYT { @@ -49,6 +50,19 @@ public: static constexpr decltype(auto) RecursiveUnwrap(U&& wrapper); using TRecursiveUnwrapped = std::remove_cvref_t<decltype(TWrapperTraits<T>::RecursiveUnwrap(std::declval<T>()))>; + + //! Unfortunatelly, clang is incapable of processing associated constraints if they depend + //! on class information (e.g. aliases and static varibles) and written out-of-line. + + //! TODO(arkady-e1ppa): Add proper constraints when clang supports them: + //! Wrap: std::same_as<std::remove_cvref_t<U>, TUnwrapped> + //! RecursiveWrap: std::same_as<std::remove_cvref_t<U>, TRecursiveUnwrapped> + //! Proper constructible_from checks? Easy for wrap, hard for recursive wrap. + template <class U> + static constexpr T Wrap(U&& unwrapped) noexcept; + + template <class U> + static constexpr T RecursiveWrap(U&& unwrapped) noexcept; }; //////////////////////////////////////////////////////////////////////////////// |
