summaryrefslogtreecommitdiffstats
path: root/library/cpp
diff options
context:
space:
mode:
authorarkady-e1ppa <[email protected]>2023-12-06 13:44:55 +0300
committerarkady-e1ppa <[email protected]>2023-12-06 14:42:52 +0300
commit10b68f0ea44b5e614b91d59a5dd5bb5a878f5eac (patch)
tree9571a47cd5426c3b9042cf3e350d05f41bd72266 /library/cpp
parentbfb11ee270b827ddd066a35ee4aa96c389c87603 (diff)
YT-20547: TIncarnationId is strongly typed
First commit
Diffstat (limited to 'library/cpp')
-rw-r--r--library/cpp/yt/misc/wrapper_traits-inl.h28
-rw-r--r--library/cpp/yt/misc/wrapper_traits.h14
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;
};
////////////////////////////////////////////////////////////////////////////////