From c0003c7d05a7c3b9602982937bb583623a820059 Mon Sep 17 00:00:00 2001 From: Yong Gyu Lee Date: Fri, 18 Oct 2024 00:36:13 +0900 Subject: [PATCH] Fix common_reference for reference_wrapper types --- .../__type_traits/basic_common_reference.h | 135 ++++++------------ ...sic_common_reference_std_specializations.h | 126 ++++++++++++++++ .../preview/__type_traits/common_reference.h | 7 +- 3 files changed, 176 insertions(+), 92 deletions(-) create mode 100644 include/preview/__type_traits/basic_common_reference_std_specializations.h diff --git a/include/preview/__type_traits/basic_common_reference.h b/include/preview/__type_traits/basic_common_reference.h index 52bab0ec..4266d9b6 100644 --- a/include/preview/__type_traits/basic_common_reference.h +++ b/include/preview/__type_traits/basic_common_reference.h @@ -5,116 +5,75 @@ #ifndef PREVIEW_TYPE_TRAITS_BASIC_COMMON_REFERENCE_H_ #define PREVIEW_TYPE_TRAITS_BASIC_COMMON_REFERENCE_H_ -#include +#include +#include "preview/__core/inline_variable.h" +#include "preview/__functional/is_reference_wrapper.h" #include "preview/__tuple/tuple_like.h" #include "preview/__type_traits/bool_constant.h" -#include "preview/__type_traits/common_reference.h" +#include "preview/__type_traits/conditional.h" +#include "preview/__type_traits/conjunction.h" +#include "preview/__type_traits/detail/tag.h" #include "preview/__type_traits/disjunction.h" -#include "preview/__type_traits/is_specialization.h" -#include "preview/__type_traits/negation.h" -#include "preview/__type_traits/no_traits.h" -#include "preview/__type_traits/type_identity.h" namespace preview { namespace detail { - -template class TQual, template class UQual, - bool = conjunction, tuple_like>::value /* false */> -struct basic_common_reference_tuple_like : no_traits {}; - -template class TQual, template class UQual, typename Index> -struct basic_common_reference_tuple_like_impl_2; - -template class TQual, template class UQual, std::size_t... I> -struct basic_common_reference_tuple_like_impl_2> { - using type = std::tuple< - common_reference_t< - TQual< std::tuple_element_t >, - UQual< std::tuple_element_t > - >... >; +namespace bcr_specialization { + +// TODO: Concept +// true specialization is defined in basic_common_reference_std_specializations.h +template::value> +struct ref_wrap_common_reference_exists_with : std::false_type {}; + +enum category_t : int { + kDefault = 0, + kTupleLike = 1, + kPair = 2, + kReferenceWrapper = 3, }; -template class TQual, template class UQual, typename Index> -struct basic_common_reference_tuple_like_impl_1; - -template class TQual, template class UQual, std::size_t... I> -struct basic_common_reference_tuple_like_impl_1> - : std::conditional_t< - conjunction< - has_typename_type< common_reference>, - UQual>> >... - >::value, - basic_common_reference_tuple_like_impl_2>, - no_traits - > {}; +template class TQual, template class UQual, + bool SatisfyRequires = /* false */ conjunction_v, tuple_like>> +struct satisfy_tuple_like_constraints : std::false_type {}; +template class TQual, template class UQual> +struct satisfy_pair_constraints : std::false_type {}; -template class TQual, template class UQual> -struct basic_common_reference_tuple_like - : std::conditional_t< - conjunction< - disjunction< is_specialization, is_specialization >, - std::is_same>, - std::is_same>, - bool_constant<(std::tuple_size>::value == std::tuple_size>::value)> - >::value, - basic_common_reference_tuple_like_impl_1>::value>>, - no_traits - > {}; +template class TQual, template class UQual, + bool SatisfyRequires = /* false */( + (ref_wrap_common_reference_exists_with, UQual>::value && + !ref_wrap_common_reference_exists_with, TQual>::value) || + (ref_wrap_common_reference_exists_with, TQual>::value && + !ref_wrap_common_reference_exists_with, UQual>::value) + )> +struct satisfy_ref_wrap_constraints : bool_constant {}; -template class TQual, template class UQual, bool /* false */> -struct basic_common_reference_pair {}; +template class TQual, template class UQual> +PREVIEW_INLINE_VARIABLE constexpr int category = preview::conditional_t< + satisfy_tuple_like_constraints , tag_v, + satisfy_pair_constraints , tag_v, + satisfy_ref_wrap_constraints , tag_v, + tag_v +>::value; -template class TQual, template class UQual> -struct basic_common_reference_pair, std::pair, TQual, UQual, true> { - using type = std::pair< common_reference_t, UQual>, - common_reference_t, UQual> >; -}; +template class TQual, template class UQual, int Tag> +struct basic_common_reference_base; -template >, - has_typename_type< common_reference > - >::value /* false */> -struct basic_common_reference_ref_wrap {}; - -template -struct basic_common_reference_ref_wrap - : std::conditional_t< - convertible_to>::value, - type_identity>, - no_traits - > {}; +template class TQual, template class UQual> +struct basic_common_reference_base {}; +} // namespace bcr_specialization } // namespace detail // Primary template template class TQual, template class UQual> -struct basic_common_reference : detail::basic_common_reference_tuple_like {}; - -// specializations of basic_common_reference -template class TQual, template class UQual> -struct basic_common_reference, std::pair, TQual, UQual> - : detail::basic_common_reference_pair< - std::pair, std::pair, +struct basic_common_reference + : detail::bcr_specialization::basic_common_reference_base< + T, U, TQual, UQual, - conjunction< - has_typename_type< common_reference< TQual, UQual > >, - has_typename_type< common_reference< TQual, UQual > > - >::value + detail::bcr_specialization::category > {}; -template class RQual, template class TQual> -struct basic_common_reference, T, RQual, TQual> - : detail::basic_common_reference_ref_wrap, TQual> {}; - -template class RQual, template class TQual> -struct basic_common_reference, TQual, RQual> - : detail::basic_common_reference_ref_wrap, TQual> {}; - - } // namespace preview #endif // PREVIEW_TYPE_TRAITS_BASIC_COMMON_REFERENCE_H_ diff --git a/include/preview/__type_traits/basic_common_reference_std_specializations.h b/include/preview/__type_traits/basic_common_reference_std_specializations.h new file mode 100644 index 00000000..f2fcb893 --- /dev/null +++ b/include/preview/__type_traits/basic_common_reference_std_specializations.h @@ -0,0 +1,126 @@ +// +// Created by yonggyulee on 2024. 10. 17. +// + +#ifndef PREVIEW_TYPE_TRAITS_BASIC_COMMON_REFERENCE_STD_SPECIALIZATIONS_H_ +#define PREVIEW_TYPE_TRAITS_BASIC_COMMON_REFERENCE_STD_SPECIALIZATIONS_H_ + +#include +#include +#include + +#include "preview/__concepts/convertible_to.h" +#include "preview/__tuple/tuple_like.h" +#include "preview/__tuple/tuple_integer_sequence.h" +#include "preview/__type_traits/basic_common_reference.h" +#include "preview/__type_traits/common_reference.h" +#include "preview/__type_traits/disjunction.h" +#include "preview/__type_traits/has_typename_type.h" +#include "preview/__type_traits/is_specialization.h" + +namespace preview { +namespace detail { +namespace bcr_specialization { + +// basic_common_reference + +template class TQual, template class UQual, typename IndexSequence> +struct satisfy_tuple_like_constraints_impl_3; +template class TQual, template class UQual, std::size_t... I> +struct satisfy_tuple_like_constraints_impl_3> : conjunction< + has_typename_type< + common_reference>, + UQual>> + >... +> {}; + +template class TQual, template class UQual, + bool = /* false */ (std::tuple_size::value == std::tuple_size::value)> +struct satisfy_tuple_like_constraints_impl_2 : std::false_type {}; + +template class TQual, template class UQual> +struct satisfy_tuple_like_constraints_impl_2 + : satisfy_tuple_like_constraints_impl_3> {}; + +template class TQual, template class UQual, + bool = /* false */ conjunction_v< + disjunction, is_specialization>, + std::is_same>, + std::is_same> + > +> +struct satisfy_tuple_like_constraints_impl : std::false_type {}; + +template class TQual, template class UQual> +struct satisfy_tuple_like_constraints_impl + : satisfy_tuple_like_constraints_impl_2 {}; + +template class TQual, template class UQual> +struct satisfy_tuple_like_constraints + : satisfy_tuple_like_constraints_impl {}; + +template class TQual, template class UQual, typename ISeq> +struct basic_common_reference_base_tuple_like; + +template class TQual, template class UQual, std::size_t... I> +struct basic_common_reference_base_tuple_like> { + using type = std::tuple< + common_reference_t, + std::tuple_element_t> + ... + >; +}; + +template class TQual, template class UQual> +struct basic_common_reference_base + : basic_common_reference_base_tuple_like> {}; + + + +// basic_const_reference + +template class TQual, template class UQual> +struct satisfy_pair_constraints, std::pair, TQual, UQual> : conjunction< + has_typename_type, UQual>>, + has_typename_type, UQual>> +> {}; + +template class TQual, template class UQual> +struct basic_common_reference_base, std::pair, TQual, UQual, kPair> { + using type = std::pair, common_reference_t>; +}; + + + +// basic_const_reference +// basic_const_reference + +template>::value> +struct ref_wrap_common_reference_exists_with_impl : std::false_type {}; + +template +struct ref_wrap_common_reference_exists_with_impl + : convertible_to> {}; + +template +struct ref_wrap_common_reference_exists_with + : ref_wrap_common_reference_exists_with_impl {}; + +template class RQual, template class TQual> +struct basic_common_reference_ref_wrap { + using type = common_reference_t>; +}; + +template class TQual, template class UQual> +struct basic_common_reference_base : std::conditional_t< + (ref_wrap_common_reference_exists_with, UQual>::value && + !ref_wrap_common_reference_exists_with, TQual>::value), + basic_common_reference_ref_wrap, + basic_common_reference_ref_wrap +> {}; + +} // namespace bcr_specialization +} // namespace detail +} // namespace preview + +#endif // PREVIEW_TYPE_TRAITS_BASIC_COMMON_REFERENCE_STD_SPECIALIZATIONS_H_ diff --git a/include/preview/__type_traits/common_reference.h b/include/preview/__type_traits/common_reference.h index bf167e1f..f710d4b3 100644 --- a/include/preview/__type_traits/common_reference.h +++ b/include/preview/__type_traits/common_reference.h @@ -10,6 +10,7 @@ #include #include "preview/__concepts/convertible_to.h" +#include "preview/__type_traits/basic_common_reference.h" #include "preview/__type_traits/conjunction.h" #include "preview/__type_traits/common_type.h" #include "preview/__type_traits/copy_cvref.h" @@ -20,10 +21,6 @@ namespace preview { -// forward declare -template class TQual, template class UQual> -struct basic_common_reference; - template struct common_reference; @@ -155,4 +152,6 @@ using common_reference_t = typename common_reference::type; } // namespace preview +#include "preview/__type_traits/basic_common_reference_std_specializations.h" + #endif // PREVIEW_TYPE_TRAITS_COMMON_REFERENCE_H_