00001 // Sh: A GPU metaprogramming language. 00002 // 00003 // Copyright 2003-2005 Serious Hack Inc. 00004 // 00005 // This library is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 // 00010 // This library is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with this library; if not, write to the Free Software 00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00018 // MA 02110-1301, USA 00020 #ifndef SHSTORAGETYPEIMPL_HPP 00021 #define SHSTORAGETYPEIMPL_HPP 00022 00023 #include <climits> 00024 #include <cmath> 00025 #include <algorithm> 00026 #include "ShStorageType.hpp" 00027 00028 namespace SH { 00029 00030 inline bool shIsFloat(ShValueType value_type) 00031 { 00032 return !shIsInvalidValueType(value_type) && 00033 (value_type & SH_VALUETYPE_TYPE_MASK) == SH_VALUETYPE_TYPE_FLOAT; 00034 } 00035 00036 inline bool shIsInteger(ShValueType value_type) 00037 { 00038 return !shIsInvalidValueType(value_type) && 00039 (value_type & SH_VALUETYPE_TYPE_MASK) == SH_VALUETYPE_TYPE_INT; 00040 } 00041 00042 inline bool shIsFraction(ShValueType value_type) 00043 { 00044 return !shIsInvalidValueType(value_type) && 00045 (value_type & SH_VALUETYPE_TYPE_MASK) == SH_VALUETYPE_TYPE_FRAC; 00046 } 00047 00048 inline bool shIsSigned(ShValueType value_type) 00049 { 00050 return !shIsInvalidValueType(value_type) && 00051 (value_type & SH_VALUETYPE_SIGNED_MASK) == SH_VALUETYPE_SIGNED; 00052 } 00053 00054 inline bool shIsRegularValueType(ShValueType value_type) 00055 { 00056 return !shIsInvalidValueType(value_type) && 00057 (value_type & SH_VALUETYPE_SPECIAL_MASK) == SH_VALUETYPE_SPECIAL_NONE; 00058 } 00059 00060 inline bool shIsInvalidValueType(ShValueType value_type) 00061 { 00062 return value_type == SH_VALUETYPE_END; 00063 } 00064 00065 inline 00066 ShValueType shRegularValueType(ShValueType value_type) 00067 { 00068 return shIsInvalidValueType(value_type) ? value_type : 00069 (value_type & ~SH_VALUETYPE_SPECIAL_MASK); 00070 } 00071 00072 /*** Implementation of the automatic promotion tree lookup 00073 * This decides the argument conversions used in operators 00074 * and the result type given by operators (and library funcs). 00075 * (The tree is built explicitly in ShTypeInfoCasts.cpp as well, 00076 * and this should match those tree edges) 00077 * 00078 * @see ShTypeInfoCasts.cpp 00079 * 00080 * Rules (checked in order until one matches) 00081 * 1) If either is double, use double 00082 * 2) If either is float or fractional, use float 00083 * 3) If both are half, use half 00084 * 4) Use int 00085 */ 00086 template<typename T1, typename T2> 00087 struct ShCommonType { 00088 static const ShValueType V1 = ShStorageTypeInfo<T1>::value_type; 00089 static const ShValueType V2 = ShStorageTypeInfo<T2>::value_type; 00090 00091 static const bool eitherDouble = V1 == SH_DOUBLE || V2 == SH_DOUBLE; 00092 static const bool eitherFloat = V1 == SH_FLOAT || V2 == SH_FLOAT; 00093 static const bool eitherFraction = ShIsFraction<T1>::matches || ShIsFraction<T2>::matches; 00094 static const bool bothHalf = V1 == SH_HALF && V2 == SH_HALF; 00095 00096 static const ShValueType value_type = 00097 (eitherDouble ? 00098 SH_DOUBLE : 00099 ((eitherFloat || eitherFraction) ? 00100 SH_FLOAT : 00101 (bothHalf ? 00102 SH_HALF : 00103 SH_INT))); 00104 00105 typedef typename ShValueTypeInfo<value_type>::storage_type type; 00106 }; 00107 #undef SH_MATCH 00108 00109 00110 } 00111 00112 #endif
1.4.3-20050530