1 //=================================================================================================
2 /*!
3 //  \file blaze/math/typetraits/UnderlyingBuiltin.h
4 //  \brief Header file for the UnderlyingBuiltin type trait
5 //
6 //  Copyright (C) 2012-2020 Klaus Iglberger - All Rights Reserved
7 //
8 //  This file is part of the Blaze library. You can redistribute it and/or modify it under
9 //  the terms of the New (Revised) BSD License. Redistribution and use in source and binary
10 //  forms, with or without modification, are permitted provided that the following conditions
11 //  are met:
12 //
13 //  1. Redistributions of source code must retain the above copyright notice, this list of
14 //     conditions and the following disclaimer.
15 //  2. Redistributions in binary form must reproduce the above copyright notice, this list
16 //     of conditions and the following disclaimer in the documentation and/or other materials
17 //     provided with the distribution.
18 //  3. Neither the names of the Blaze development group nor the names of its contributors
19 //     may be used to endorse or promote products derived from this software without specific
20 //     prior written permission.
21 //
22 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
23 //  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 //  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 //  SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 //  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 //  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 //  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 //  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 //  DAMAGE.
32 */
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_TYPETRAITS_UNDERLYINGBUILTIN_H_
36 #define _BLAZE_MATH_TYPETRAITS_UNDERLYINGBUILTIN_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/util/EnableIf.h>
44 #include <blaze/util/typetraits/IsSame.h>
45 #include <blaze/util/typetraits/RemoveCV.h>
46 
47 
48 namespace blaze {
49 
50 //=================================================================================================
51 //
52 //  CLASS DEFINITION
53 //
54 //=================================================================================================
55 
56 //*************************************************************************************************
57 /*! \cond BLAZE_INTERNAL */
58 template< typename, typename = void > struct UnderlyingBuiltinHelper1;
59 template< typename, typename = void > struct UnderlyingBuiltinHelper2;
60 /*! \endcond */
61 //*************************************************************************************************
62 
63 
64 //*************************************************************************************************
65 /*!\brief Evaluation of the underlying builtin element type of a given data type.
66 // \ingroup math_type_traits
67 //
68 // This type trait evaluates the underlying fundamental element type at the heart of the given
69 // data type \a T. For this purpose either a nested \a ElementType or a nested \a value_type will
70 // be used. Examples:
71 
72    \code
73    using Type1 = double;                                    // Built-in data type
74    using Type2 = complex<float>;                            // Complex data type
75    using Type3 = std::vector<short>;                        // std::vector with built-in element type
76    using Type4 = StaticVector<int,3UL>;                     // Vector with built-in element type
77    using Type5 = CompressedVector< DynamicVector<float> >;  // Vector with vector element type
78 
79    blaze::UnderlyingBuiltin< Type1 >::Type  // corresponds to double
80    blaze::UnderlyingBuiltin< Type2 >::Type  // corresponds to float
81    blaze::UnderlyingBuiltin< Type3 >::Type  // corresponds to short
82    blaze::UnderlyingBuiltin< Type4 >::Type  // corresponds to int
83    blaze::UnderlyingBuiltin< Type5 >::Type  // corresponds to float
84    \endcode
85 
86 // Note that it is possible to add support for other data types that have an underlying
87 // fundamental element type but do neither provide a nested \a ElementType nor \a value_type type
88 // by specializing the UnderlyingBuiltin class template.
89 */
90 template< typename T >
91 struct UnderlyingBuiltin
92 {
93  public:
94    //**********************************************************************************************
95    /*! \cond BLAZE_INTERNAL */
96    using Type = typename UnderlyingBuiltinHelper1< RemoveCV_t<T> >::Type;
97    /*! \endcond */
98    //**********************************************************************************************
99 };
100 //*************************************************************************************************
101 
102 
103 //*************************************************************************************************
104 /*!\brief Auxiliary alias declaration for the UnderlyingBuiltin type trait.
105 // \ingroup math_type_traits
106 //
107 // The UnderlyingBuiltin_t alias declaration provides a convenient shortcut to access the
108 // nested \a Type of the UnderlyingBuiltin class template. For instance, given the type \a T
109 // the following two type definitions are identical:
110 
111    \code
112    using Type1 = typename blaze::UnderlyingBuiltin<T>::Type;
113    using Type2 = blaze::UnderlyingBuiltin_t<T>;
114    \endcode
115 */
116 template< typename T >
117 using UnderlyingBuiltin_t = typename UnderlyingBuiltin<T>::Type;
118 //*************************************************************************************************
119 
120 
121 //*************************************************************************************************
122 /*! \cond BLAZE_INTERNAL */
123 /*!\brief First auxiliary helper struct for the UnderlyingBuiltin type trait.
124 // \ingroup math_type_traits
125 */
126 template< typename T, typename >
127 struct UnderlyingBuiltinHelper1
128 {
129    using Type = typename UnderlyingBuiltinHelper2<T>::Type;
130 };
131 
132 template< typename T >
133 struct UnderlyingBuiltinHelper1< T, EnableIf_t< !IsSame_v< T, typename T::ElementType > > >
134 {
135    using Type = typename UnderlyingBuiltinHelper1< typename T::ElementType >::Type;
136 };
137 /*! \endcond */
138 //*************************************************************************************************
139 
140 
141 //*************************************************************************************************
142 /*! \cond BLAZE_INTERNAL */
143 /*!\brief Second auxiliary helper struct for the UnderlyingBuiltin type trait.
144 // \ingroup math_type_traits
145 */
146 template< typename T, typename >
147 struct UnderlyingBuiltinHelper2
148 {
149    using Type = T;
150 };
151 
152 template< typename T >
153 struct UnderlyingBuiltinHelper2< T, EnableIf_t< !IsSame_v< T, typename T::value_type > > >
154 {
155    using Type = typename UnderlyingBuiltinHelper1< typename T::value_type >::Type;
156 };
157 /*! \endcond */
158 //*************************************************************************************************
159 
160 } // namespace blaze
161 
162 #endif
163