ShStorageType.hpp

00001 // Sh: A GPU metaprogramming language.
00002 //
00003 // Copyright 2003-2006 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 SHSTORAGETYPE_HPP
00021 #define SHSTORAGETYPE_HPP
00022 
00023 #include "ShUtility.hpp"
00024 #include "ShVariableType.hpp"
00025 #include "ShHalf.hpp"
00026 #include "ShFraction.hpp"
00027 
00034 namespace SH {
00035 
00037 struct ShInvalidStorageType {};
00038 
00051 typedef unsigned int ShValueType;
00052 enum __ShValueTypeEnum {
00053   SH_HALF       = 0x0001, 
00054   SH_FLOAT      = 0x0002, 
00055   SH_DOUBLE     = 0x0003, 
00056 
00057   SH_BYTE       = 0x0010,
00058   SH_SHORT      = 0x0011,
00059   SH_INT        = 0x0012,
00060 
00061   SH_UBYTE      = 0x0018,
00062   SH_USHORT     = 0x0019,
00063   SH_UINT       = 0x001A,
00064 
00065   SH_FBYTE      = 0x0020,
00066   SH_FSHORT     = 0x0021,
00067   SH_FINT       = 0x0022,
00068 
00069   SH_FUBYTE     = 0x0028,
00070   SH_FUSHORT    = 0x0029,
00071   SH_FUINT      = 0x002A,
00072 
00073   SH_I_HALF    = 0x0101,
00074   SH_I_FLOAT   = 0x0102,
00075   SH_I_DOUBLE  = 0x0103,
00076 
00077   SH_A_HALF    = 0x0201,
00078   SH_A_FLOAT   = 0x0202,
00079   SH_A_DOUBLE  = 0x0203,
00080 
00081   SH_VALUETYPE_SIZE_MASK = 0x0007,
00082 
00083   SH_VALUETYPE_SIGNED_MASK = 0x0008,
00084   SH_VALUETYPE_SIGNED = 0x0000,
00085 
00086   SH_VALUETYPE_TYPE_MASK = 0x00F0,
00087   SH_VALUETYPE_TYPE_FLOAT = 0x0000,
00088   SH_VALUETYPE_TYPE_INT   = 0x0010,
00089   SH_VALUETYPE_TYPE_FRAC  = 0x0020,
00090 
00091   SH_VALUETYPE_SPECIAL_MASK = 0x7F00, 
00092   SH_VALUETYPE_SPECIAL_NONE = 0x0000, 
00093   SH_VALUETYPE_SPECIAL_I    = 0x0100, 
00094   SH_VALUETYPE_SPECIAL_A    = 0x0200, 
00095 
00096   SH_VALUETYPE_END = 0xFFFF
00097 };
00098 // @}
00099 
00105 bool shIsFloat(ShValueType value_type);
00106 bool shIsInteger(ShValueType value_type);
00107 bool shIsFraction(ShValueType value_type);
00108 
00109 bool shIsSigned(ShValueType value_type);
00110 
00111 bool shIsRegularValueType(ShValueType value_type);
00112 
00113 bool shIsInvalidValueType(ShValueType value_type);
00114 // @}
00115 
00118 template<ShValueType V> struct __ShValueToStorageType { typedef ShInvalidStorageType type; };
00119 template<typename T> struct __ShStorageToValueType { static const ShValueType type = SH_VALUETYPE_END; };
00120 
00121 #define SH_VALUE_STORAGE_TYPE_MAPPING(V, T)\
00122   template<> struct __ShValueToStorageType<V >    { typedef T type; }; \
00123   template<> struct __ShStorageToValueType<T >    { static const ShValueType type = V; }; 
00124 
00125 SH_VALUE_STORAGE_TYPE_MAPPING(SH_HALF,    ShHalf); 
00126 SH_VALUE_STORAGE_TYPE_MAPPING(SH_FLOAT,   float); 
00127 SH_VALUE_STORAGE_TYPE_MAPPING(SH_DOUBLE,  double); 
00128 
00129 SH_VALUE_STORAGE_TYPE_MAPPING(SH_BYTE,    char); 
00130 SH_VALUE_STORAGE_TYPE_MAPPING(SH_SHORT,   short); 
00131 SH_VALUE_STORAGE_TYPE_MAPPING(SH_INT,     int); 
00132 SH_VALUE_STORAGE_TYPE_MAPPING(SH_UBYTE,   unsigned char); 
00133 SH_VALUE_STORAGE_TYPE_MAPPING(SH_USHORT,  unsigned short); 
00134 SH_VALUE_STORAGE_TYPE_MAPPING(SH_UINT,    unsigned int); 
00135 
00136 SH_VALUE_STORAGE_TYPE_MAPPING(SH_FBYTE,   ShFracByte); 
00137 SH_VALUE_STORAGE_TYPE_MAPPING(SH_FSHORT,  ShFracShort); 
00138 SH_VALUE_STORAGE_TYPE_MAPPING(SH_FINT,    ShFracInt); 
00139 SH_VALUE_STORAGE_TYPE_MAPPING(SH_FUBYTE,  ShFracUByte); 
00140 SH_VALUE_STORAGE_TYPE_MAPPING(SH_FUSHORT, ShFracUShort); 
00141 SH_VALUE_STORAGE_TYPE_MAPPING(SH_FUINT,   ShFracUInt); 
00142 
00143 // @}
00144 
00147 template<typename T> struct __ShStorageTypeName { static const char* name; };
00148 template<typename T> const char* __ShStorageTypeName<T>::name = "unknown";
00149 
00150 #define SH_STORAGETYPE_NAME_SPEC(T)\
00151   template<> struct SH_DLLEXPORT __ShStorageTypeName<T > { static const char* name; };
00152 
00153 SH_STORAGETYPE_NAME_SPEC(ShHalf);
00154 SH_STORAGETYPE_NAME_SPEC(float);
00155 SH_STORAGETYPE_NAME_SPEC(double);
00156 
00157 SH_STORAGETYPE_NAME_SPEC(char);
00158 SH_STORAGETYPE_NAME_SPEC(short);
00159 SH_STORAGETYPE_NAME_SPEC(int);
00160 SH_STORAGETYPE_NAME_SPEC(unsigned char);
00161 SH_STORAGETYPE_NAME_SPEC(unsigned short);
00162 SH_STORAGETYPE_NAME_SPEC(unsigned int);
00163 
00164 SH_STORAGETYPE_NAME_SPEC(ShFracByte);
00165 SH_STORAGETYPE_NAME_SPEC(ShFracShort);
00166 SH_STORAGETYPE_NAME_SPEC(ShFracInt);
00167 SH_STORAGETYPE_NAME_SPEC(ShFracUByte);
00168 SH_STORAGETYPE_NAME_SPEC(ShFracUShort);
00169 SH_STORAGETYPE_NAME_SPEC(ShFracUInt);
00170 
00171 #undef SH_STORAGETYPE_NAME_SPEC
00172 
00173 
00174 
00175 
00178 template<typename T>
00179 struct ShIsFraction: public MatchTemplateType<T, ShFraction> {};
00181 
00185 template<ShValueType V>
00186 struct __ShRegularValueType 
00187 {
00188   static const ShValueType type = (V & ~SH_VALUETYPE_SPECIAL_MASK); 
00189 };
00190 
00191 template<typename T>
00192 struct __ShRegularStorageType
00193 {
00194   static const ShValueType range_value_type = __ShStorageToValueType<T>::type;
00195   static const ShValueType value_type = __ShRegularValueType<range_value_type>::type; 
00196   typedef typename __ShValueToStorageType<value_type>::type type; 
00197 };
00198 
00199 inline 
00200 ShValueType shRegularValueType(ShValueType value_type); 
00201 // @}
00202 
00206 template<typename T1, typename T2>
00207 struct ShCommonType;
00208 
00209 template<typename T1, typename T2, typename T3>
00210 struct ShCommonType3 {
00211   typedef typename ShCommonType<typename ShCommonType<T1, T2>::type, T3>::type type; 
00212 };
00213 
00214 template<typename T1, typename T2, typename T3, typename T4>
00215 struct ShCommonType4 {
00216   typedef typename ShCommonType<typename ShCommonType<T1, T2>::type, 
00217                                 typename ShCommonType<T3, T4>::type>::type type; 
00218 };
00219 // @}
00220 
00224 template<typename T>
00225 struct ShStorageTypeInfo {
00226   typedef T storage_type;
00227   static const ShValueType value_type = __ShStorageToValueType<T>::type; 
00228 
00229 
00231   typedef typename __ShRegularStorageType<T>::type RegularType;
00232   static const ShValueType RegularValueType = __ShStorageToValueType<RegularType>::type;
00233 
00234   // @todo not sure we want all of these here, since there could be user-defined 
00235   // special types too.  This might be too restrictive if we depend on these. 
00236 
00237   static const char* name; 
00238 
00239   // @todo type include here the ability to set available operations 
00240 
00241   // @todo type include here ShPrograms for transforming from this
00242   // storage type to a set of different ones, allowing the transformers
00243   // to choose the best conversions.
00244 
00245   // once the above two things are complete, than user-defined types should
00246   // work just fine.
00247 };
00248 
00249 template<typename T>
00250 const char* ShStorageTypeInfo<T>::name = __ShStorageTypeName<T>::name;
00251 
00252 
00254 
00258 template<ShValueType V>
00259 struct ShValueTypeInfo: public ShStorageTypeInfo<typename __ShValueToStorageType<V>::type> {
00260 };
00261 
00262 }
00263 
00264 #include "ShStorageTypeImpl.hpp"
00265 
00266 #endif

Generated on Thu Feb 16 14:51:38 2006 for Sh by  doxygen 1.4.6