wrapper_traits-inl.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #ifndef WRAPPER_TRAITS_INL_H_
  2. #error "Direct inclusion of this file is not allowed, include wrapper_traits.h"
  3. // For the sake of sane code completion.
  4. #include "wrapper_traits.h"
  5. #endif
  6. #include <library/cpp/yt/assert/assert.h>
  7. #include <optional>
  8. namespace NYT {
  9. ////////////////////////////////////////////////////////////////////////////////
  10. template <class T>
  11. requires std::is_object_v<T>
  12. template <class U>
  13. requires std::same_as<std::remove_cvref_t<U>, T>
  14. constexpr decltype(auto) TBasicWrapperTraits<T>::Unwrap(U&& wrapper) noexcept
  15. {
  16. return std::forward<U>(wrapper);
  17. }
  18. template <class T>
  19. requires std::is_object_v<T>
  20. constexpr bool TBasicWrapperTraits<T>::HasValue(const T&) noexcept
  21. {
  22. return true;
  23. }
  24. ////////////////////////////////////////////////////////////////////////////////
  25. template <class T>
  26. requires std::is_object_v<T>
  27. template <class U>
  28. requires std::same_as<std::remove_cvref_t<U>, T>
  29. constexpr decltype(auto) TWrapperTraits<T>::Unwrap(U&& wrapper)
  30. {
  31. YT_VERIFY(HasValue(wrapper));
  32. return TBasicWrapperTraits<T>::Unwrap(std::forward<U>(wrapper));
  33. }
  34. template <class T>
  35. requires std::is_object_v<T>
  36. template <class U>
  37. requires std::same_as<std::remove_cvref_t<U>, T>
  38. constexpr decltype(auto) TWrapperTraits<T>::RecursiveUnwrap(U&& wrapper)
  39. {
  40. using TDecayedU = std::remove_cvref_t<U>;
  41. using TTraits = TWrapperTraits<TDecayedU>;
  42. using TInnerTraits = TWrapperTraits<typename TTraits::TUnwrapped>;
  43. if constexpr (CNonTrivialWrapper<TDecayedU>) {
  44. return TInnerTraits::RecursiveUnwrap(TTraits::Unwrap(std::forward<U>(wrapper)));
  45. } else {
  46. return TTraits::Unwrap(std::forward<U>(wrapper));
  47. }
  48. }
  49. template <class T>
  50. requires std::is_object_v<T>
  51. constexpr bool TWrapperTraits<T>::HasValue(const T& wrapper) noexcept
  52. {
  53. return TBasicWrapperTraits<T>::HasValue(wrapper);
  54. }
  55. template <class T>
  56. requires std::is_object_v<T>
  57. constexpr bool TWrapperTraits<T>::RecursiveHasValue(const T& wrapper) noexcept
  58. {
  59. using TTraits = TWrapperTraits<T>;
  60. using TInnerTraits = TWrapperTraits<typename TTraits::TUnwrapped>;
  61. if constexpr (CNonTrivialWrapper<T>) {
  62. return TTraits::HasValue(wrapper) && TInnerTraits::HasValue(TTraits::Unwrap(wrapper));
  63. } else {
  64. return TTraits::HasValue(wrapper);
  65. }
  66. }
  67. template <class T>
  68. requires std::is_object_v<T>
  69. template <class U>
  70. constexpr T TWrapperTraits<T>::Wrap(U&& unwrapped) noexcept
  71. {
  72. static_assert(std::same_as<std::remove_cvref_t<U>, TUnwrapped>);
  73. return T(std::forward<U>(unwrapped));
  74. }
  75. template <class T>
  76. requires std::is_object_v<T>
  77. template <class U>
  78. constexpr T TWrapperTraits<T>::RecursiveWrap(U&& unwrapped) noexcept
  79. {
  80. using TTraits = TWrapperTraits<T>;
  81. using TInnerTraits = TWrapperTraits<typename TTraits::TUnwrapped>;
  82. if constexpr (CNonTrivialWrapper<TUnwrapped>) {
  83. return TTraits::Wrap(TInnerTraits::RecursiveWrap(std::forward<U>(unwrapped)));
  84. } else {
  85. //! U == TUnwrapped.
  86. return TTraits::Wrap(std::forward<U>(unwrapped));
  87. }
  88. }
  89. ////////////////////////////////////////////////////////////////////////////////
  90. //! Some standard library specializations
  91. ////////////////////////////////////////////////////////////////////////////////
  92. template <class T>
  93. struct TBasicWrapperTraits<std::optional<T>>
  94. {
  95. static constexpr bool IsTrivialWrapper = false;
  96. using TUnwrapped = T;
  97. static constexpr bool HasValue(const std::optional<T>& optional) noexcept
  98. {
  99. return optional.has_value();
  100. }
  101. template <class U>
  102. requires std::same_as<std::remove_cvref_t<U>, std::optional<T>>
  103. static constexpr decltype(auto) Unwrap(U&& optional)
  104. {
  105. return *std::forward<U>(optional);
  106. }
  107. };
  108. ////////////////////////////////////////////////////////////////////////////////
  109. } // namespace NYT