#ifndef WRAPPER_TRAITS_INL_H_ #error "Direct inclusion of this file is not allowed, include wrapper_traits.h" // For the sake of sane code completion. #include "wrapper_traits.h" #endif #include #include namespace NYT { //////////////////////////////////////////////////////////////////////////////// template requires std::is_object_v template requires std::same_as, T> constexpr decltype(auto) TBasicWrapperTraits::Unwrap(U&& wrapper) noexcept { return std::forward(wrapper); } template requires std::is_object_v constexpr bool TBasicWrapperTraits::HasValue(const T&) noexcept { return true; } //////////////////////////////////////////////////////////////////////////////// template requires std::is_object_v template requires std::same_as, T> constexpr decltype(auto) TWrapperTraits::Unwrap(U&& wrapper) { YT_VERIFY(HasValue(wrapper)); return TBasicWrapperTraits::Unwrap(std::forward(wrapper)); } template requires std::is_object_v template requires std::same_as, T> constexpr decltype(auto) TWrapperTraits::RecursiveUnwrap(U&& wrapper) { using TDecayedU = std::remove_cvref_t; using TTraits = TWrapperTraits; using TInnerTraits = TWrapperTraits; if constexpr (CNonTrivialWrapper) { return TInnerTraits::RecursiveUnwrap(TTraits::Unwrap(std::forward(wrapper))); } else { return TTraits::Unwrap(std::forward(wrapper)); } } template requires std::is_object_v constexpr bool TWrapperTraits::HasValue(const T& wrapper) noexcept { return TBasicWrapperTraits::HasValue(wrapper); } template requires std::is_object_v constexpr bool TWrapperTraits::RecursiveHasValue(const T& wrapper) noexcept { using TTraits = TWrapperTraits; using TInnerTraits = TWrapperTraits; if constexpr (CNonTrivialWrapper) { return TTraits::HasValue(wrapper) && TInnerTraits::HasValue(TTraits::Unwrap(wrapper)); } else { return TTraits::HasValue(wrapper); } } template requires std::is_object_v template constexpr T TWrapperTraits::Wrap(U&& unwrapped) noexcept { static_assert(std::same_as, TUnwrapped>); return T(std::forward(unwrapped)); } template requires std::is_object_v template constexpr T TWrapperTraits::RecursiveWrap(U&& unwrapped) noexcept { using TTraits = TWrapperTraits; using TInnerTraits = TWrapperTraits; if constexpr (CNonTrivialWrapper) { return TTraits::Wrap(TInnerTraits::RecursiveWrap(std::forward(unwrapped))); } else { //! U == TUnwrapped. return TTraits::Wrap(std::forward(unwrapped)); } } //////////////////////////////////////////////////////////////////////////////// //! Some standard library specializations //////////////////////////////////////////////////////////////////////////////// template struct TBasicWrapperTraits> { static constexpr bool IsTrivialWrapper = false; using TUnwrapped = T; static constexpr bool HasValue(const std::optional& optional) noexcept { return optional.has_value(); } template requires std::same_as, std::optional> static constexpr decltype(auto) Unwrap(U&& optional) { return *std::forward(optional); } }; //////////////////////////////////////////////////////////////////////////////// } // namespace NYT