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 | |
| parent | bfb11ee270b827ddd066a35ee4aa96c389c87603 (diff) | |
YT-20547: TIncarnationId is strongly typed
First commit
Diffstat (limited to 'library/cpp')
| -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;  };  ////////////////////////////////////////////////////////////////////////////////  | 
