Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <complex> 7 : #include <type_traits> 8 : 9 : #include "Utilities/NoSuchType.hpp" 10 : #include "Utilities/TMPL.hpp" 11 : #include "Utilities/TypeTraits/CreateHasTypeAlias.hpp" 12 : #include "Utilities/TypeTraits/IsComplexOfFundamental.hpp" 13 : 14 : namespace tt { 15 : namespace detail { 16 : // NOLINTBEGIN(clang-diagnostic-unused-const-variable) 17 : CREATE_HAS_TYPE_ALIAS(ElementType) 18 : CREATE_HAS_TYPE_ALIAS_V(ElementType) 19 : CREATE_HAS_TYPE_ALIAS(value_type) 20 : CREATE_HAS_TYPE_ALIAS_V(value_type) 21 : // NOLINTEND(clang-diagnostic-unused-const-variable) 22 : } // namespace detail 23 : /// @{ 24 : /// \ingroup TypeTraitsGroup 25 : /// \brief Extracts the fundamental type for a container 26 : /// 27 : /// \details Designates a type alias `get_fundamental_type::type` 28 : /// as `T` when `T` itself is an appropriate fundamental type, and the 29 : /// contained type of a container which specifies a `value_type`. 30 : /// 31 : /// `get_fundamental_type_t<T>` is provided as a type alias to 32 : /// `type` from `get_fundamental_type<T>` 33 : /// 34 : /// \snippet Test_GetFundamentalType.cpp get_fundamental_type 35 : template <typename T, typename = std::nullptr_t> 36 1 : struct get_fundamental_type { 37 0 : using type = tmpl::conditional_t<std::is_fundamental_v<T>, T, NoSuchType>; 38 : }; 39 : 40 : /// \cond 41 : // Specialization for Blaze expressions 42 : template <typename T> 43 : struct get_fundamental_type<T, Requires<detail::has_ElementType_v<T>>> { 44 : using type = typename get_fundamental_type<typename T::ElementType>::type; 45 : }; 46 : // Specialization for containers 47 : template <typename T> 48 : struct get_fundamental_type<T, Requires<detail::has_value_type_v<T> and 49 : not detail::has_ElementType_v<T>>> { 50 : using type = typename get_fundamental_type<typename T::value_type>::type; 51 : }; 52 : /// \endcond 53 : 54 : template <typename T> 55 0 : using get_fundamental_type_t = typename get_fundamental_type<T>::type; 56 : /// @} 57 : 58 : template <typename T, typename = std::nullptr_t> 59 0 : struct get_complex_or_fundamental_type { 60 0 : using type = 61 : std::conditional_t<tt::is_complex_or_fundamental_v<T>, T, NoSuchType>; 62 : }; 63 : 64 : /// \cond 65 : // Specialization for Blaze expressions 66 : template <typename T> 67 : struct get_complex_or_fundamental_type<T, 68 : Requires<detail::has_ElementType_v<T>>> { 69 : using type = 70 : typename get_complex_or_fundamental_type<typename T::ElementType>::type; 71 : }; 72 : // Specialization for containers 73 : template <typename T> 74 : struct get_complex_or_fundamental_type< 75 : T, Requires<detail::has_value_type_v<T> and 76 : not detail::has_ElementType_v<T> and 77 : not tt::is_complex_or_fundamental_v<T>>> { 78 : using type = 79 : typename get_complex_or_fundamental_type<typename T::value_type>::type; 80 : }; 81 : /// \endcond 82 : 83 : template <typename T> 84 0 : using get_complex_or_fundamental_type_t = 85 : typename get_complex_or_fundamental_type<T>::type; 86 : 87 : } // namespace tt