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
|