Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ShStorageType.hpp

00001 // Sh: A GPU metaprogramming language.
00002 //
00003 // Copyright (c) 2003 University of Waterloo Computer Graphics Laboratory
00004 // Project administrator: Michael D. McCool
00005 // Authors: Zheng Qin, Stefanus Du Toit, Kevin Moule, Tiberiu S. Popa,
00006 //          Michael D. McCool
00007 // 
00008 // This software is provided 'as-is', without any express or implied
00009 // warranty. In no event will the authors be held liable for any damages
00010 // arising from the use of this software.
00011 // 
00012 // Permission is granted to anyone to use this software for any purpose,
00013 // including commercial applications, and to alter it and redistribute it
00014 // freely, subject to the following restrictions:
00015 // 
00016 // 1. The origin of this software must not be misrepresented; you must
00017 // not claim that you wrote the original software. If you use this
00018 // software in a product, an acknowledgment in the product documentation
00019 // would be appreciated but is not required.
00020 // 
00021 // 2. Altered source versions must be plainly marked as such, and must
00022 // not be misrepresented as being the original software.
00023 // 
00024 // 3. This notice may not be removed or altered from any source
00025 // distribution.
00027 #ifndef SHSTORAGETYPE_HPP
00028 #define SHSTORAGETYPE_HPP
00029 
00030 #include "ShUtility.hpp"
00031 #include "ShVariableType.hpp"
00032 #include "ShInterval.hpp"
00033 #include "ShHalf.hpp"
00034 #include "ShFraction.hpp"
00035 
00042 namespace SH {
00043 
00045 struct ShInvalidStorageType {};
00046 
00059 typedef unsigned int ShValueType;
00060 enum __ShValueTypeEnum {
00061   SH_HALF       = 0x0001, 
00062   SH_FLOAT      = 0x0002, 
00063   SH_DOUBLE     = 0x0003, 
00064 
00065   SH_BYTE       = 0x0010,
00066   SH_SHORT      = 0x0011,
00067   SH_INT        = 0x0012,
00068 
00069   SH_UBYTE      = 0x0018,
00070   SH_USHORT     = 0x0019,
00071   SH_UINT       = 0x001A,
00072 
00073   SH_FBYTE      = 0x0020,
00074   SH_FSHORT     = 0x0021,
00075   SH_FINT       = 0x0022,
00076 
00077   SH_FUBYTE     = 0x0028,
00078   SH_FUSHORT    = 0x0029,
00079   SH_FUINT      = 0x002A,
00080 
00081   SH_I_HALF    = 0x0101,
00082   SH_I_FLOAT   = 0x0102,
00083   SH_I_DOUBLE  = 0x0103,
00084 
00085   SH_A_HALF    = 0x0201,
00086   SH_A_FLOAT   = 0x0202,
00087   SH_A_DOUBLE  = 0x0203,
00088 
00089   SH_VALUETYPE_SIZE_MASK = 0x0007,
00090 
00091   SH_VALUETYPE_SIGNED_MASK = 0x0008,
00092   SH_VALUETYPE_SIGNED = 0x0000,
00093 
00094   SH_VALUETYPE_TYPE_MASK = 0x00F0,
00095   SH_VALUETYPE_TYPE_FLOAT = 0x0000,
00096   SH_VALUETYPE_TYPE_INT   = 0x0010,
00097   SH_VALUETYPE_TYPE_FRAC  = 0x0020,
00098 
00099   SH_VALUETYPE_SPECIAL_MASK = 0x7F00, 
00100   SH_VALUETYPE_SPECIAL_NONE = 0x0100, 
00101   SH_VALUETYPE_SPECIAL_I    = 0x0100, 
00102   SH_VALUETYPE_SPECIAL_A    = 0x0200, 
00103 
00104   SH_VALUETYPE_END = 0xFFFF
00105 };
00106 // @}
00107 
00113 bool shIsFloat(ShValueType value_type);
00114 bool shIsInteger(ShValueType value_type);
00115 bool shIsFraction(ShValueType value_type);
00116 
00117 bool shIsSigned(ShValueType value_type);
00118 
00119 bool shIsRegularValueType(ShValueType value_type);
00120 bool shIsInterval(ShValueType value_type);
00121 
00122 bool shIsInvalidValueType(ShValueType value_type);
00123 // @}
00124 
00127 template<ShValueType V> struct __ShValueToStorageType { typedef ShInvalidStorageType type; };
00128 template<typename T> struct __ShStorageToValueType { static const ShValueType type = SH_VALUETYPE_END; };
00129 
00130 #define SH_VALUE_STORAGE_TYPE_MAPPING(V, T)\
00131   template<> struct __ShValueToStorageType<V >    { typedef T type; }; \
00132   template<> struct __ShStorageToValueType<T >    { static const ShValueType type = V; }; 
00133 
00134 SH_VALUE_STORAGE_TYPE_MAPPING(SH_HALF,    ShHalf); 
00135 SH_VALUE_STORAGE_TYPE_MAPPING(SH_FLOAT,   float); 
00136 SH_VALUE_STORAGE_TYPE_MAPPING(SH_DOUBLE,  double); 
00137 
00138 SH_VALUE_STORAGE_TYPE_MAPPING(SH_BYTE,    char); 
00139 SH_VALUE_STORAGE_TYPE_MAPPING(SH_SHORT,   short); 
00140 SH_VALUE_STORAGE_TYPE_MAPPING(SH_INT,     int); 
00141 SH_VALUE_STORAGE_TYPE_MAPPING(SH_UBYTE,   unsigned char); 
00142 SH_VALUE_STORAGE_TYPE_MAPPING(SH_USHORT,  unsigned short); 
00143 SH_VALUE_STORAGE_TYPE_MAPPING(SH_UINT,    unsigned int); 
00144 
00145 SH_VALUE_STORAGE_TYPE_MAPPING(SH_FBYTE,   ShFracByte); 
00146 SH_VALUE_STORAGE_TYPE_MAPPING(SH_FSHORT,  ShFracShort); 
00147 SH_VALUE_STORAGE_TYPE_MAPPING(SH_FINT,    ShFracInt); 
00148 SH_VALUE_STORAGE_TYPE_MAPPING(SH_FUBYTE,  ShFracUByte); 
00149 SH_VALUE_STORAGE_TYPE_MAPPING(SH_FUSHORT, ShFracUShort); 
00150 SH_VALUE_STORAGE_TYPE_MAPPING(SH_FUINT,   ShFracUInt); 
00151 
00152 SH_VALUE_STORAGE_TYPE_MAPPING(SH_I_HALF,  ShInterval<ShHalf>); 
00153 SH_VALUE_STORAGE_TYPE_MAPPING(SH_I_FLOAT, ShInterval<float>); 
00154 SH_VALUE_STORAGE_TYPE_MAPPING(SH_I_DOUBLE,ShInterval<double>); 
00155 
00156 // @}
00157 
00160 template<typename T> struct __ShStorageTypeName { static const char* name; };
00161 template<typename T> const char* __ShStorageTypeName<T>::name = "unknown";
00162 
00163 #define SH_STORAGETYPE_NAME_SPEC(T)\
00164   template<> struct SH_DLLEXPORT __ShStorageTypeName<T > { static const char* name; };
00165 
00166 SH_STORAGETYPE_NAME_SPEC(ShHalf);
00167 SH_STORAGETYPE_NAME_SPEC(float);
00168 SH_STORAGETYPE_NAME_SPEC(double);
00169 
00170 SH_STORAGETYPE_NAME_SPEC(char);
00171 SH_STORAGETYPE_NAME_SPEC(short);
00172 SH_STORAGETYPE_NAME_SPEC(int);
00173 SH_STORAGETYPE_NAME_SPEC(unsigned char);
00174 SH_STORAGETYPE_NAME_SPEC(unsigned short);
00175 SH_STORAGETYPE_NAME_SPEC(unsigned int);
00176 
00177 SH_STORAGETYPE_NAME_SPEC(ShFracByte);
00178 SH_STORAGETYPE_NAME_SPEC(ShFracShort);
00179 SH_STORAGETYPE_NAME_SPEC(ShFracInt);
00180 SH_STORAGETYPE_NAME_SPEC(ShFracUByte);
00181 SH_STORAGETYPE_NAME_SPEC(ShFracUShort);
00182 SH_STORAGETYPE_NAME_SPEC(ShFracUInt);
00183 
00184 SH_STORAGETYPE_NAME_SPEC(ShInterval<ShHalf>);
00185 SH_STORAGETYPE_NAME_SPEC(ShInterval<float>);
00186 SH_STORAGETYPE_NAME_SPEC(ShInterval<double>);
00187 
00188 #undef SH_STORAGETYPE_NAME_SPEC
00189 
00190 
00191 
00192 
00195 template<typename T>
00196 struct ShIsInterval: public MatchTemplateType<T, ShInterval> {};
00198 
00201 template<typename T>
00202 struct ShIsFraction: public MatchTemplateType<T, ShFraction> {};
00204 
00209 template<typename T>
00210 struct __ShIntervalStorageType
00211 {
00212   static const bool invalid = MatchType<T, ShInvalidStorageType>::matches;
00213   static const bool is_interval = ShIsInterval<T>::matches;
00214   // @todo range - this doesn't quite work once we have other special types,
00215   // perhaps...
00216   typedef typename SelectType<invalid, ShInvalidStorageType, 
00217            typename SelectType<is_interval, T, ShInterval<T> >::type>::type type; 
00218 };
00219 
00220 inline 
00221 ShValueType shIntervalValueType(ShValueType value_type); 
00222 // @}
00223 
00227 template<ShValueType V>
00228 struct __ShRegularValueType 
00229 {
00230   static const ShValueType type = (V & ~SH_VALUETYPE_SPECIAL_MASK); 
00231 };
00232 
00233 template<typename T>
00234 struct __ShRegularStorageType
00235 {
00236   static const ShValueType range_value_type = __ShStorageToValueType<T>::type;
00237   static const ShValueType value_type = __ShRegularValueType<range_value_type>::type; 
00238   typedef typename __ShValueToStorageType<value_type>::type type; 
00239 };
00240 
00241 inline 
00242 ShValueType shRegularValueType(ShValueType value_type); 
00243 // @}
00244 
00248 template<typename T1, typename T2>
00249 struct ShCommonType;
00250 
00251 template<typename T1, typename T2, typename T3>
00252 struct ShCommonType3 {
00253   typedef typename ShCommonType<typename ShCommonType<T1, T2>::type, T3>::type type; 
00254 };
00255 
00256 template<typename T1, typename T2, typename T3, typename T4>
00257 struct ShCommonType4 {
00258   typedef typename ShCommonType<typename ShCommonType<T1, T2>::type, 
00259                                 typename ShCommonType<T3, T4>::type>::type type; 
00260 };
00261 // @}
00262 
00266 template<typename T>
00267 struct ShStorageTypeInfo {
00268   typedef T storage_type;
00269   static const ShValueType value_type = __ShStorageToValueType<T>::type; 
00270 
00271 
00273   typedef typename __ShRegularStorageType<T>::type RegularType;
00274   static const ShValueType RegularValueType = __ShStorageToValueType<RegularType>::type;
00275 
00276   // @todo not sure we want all of these here, since there could be user-defined 
00277   // special types too.  This might be too restrictive if we depend on these. 
00278 
00281   typedef typename __ShIntervalStorageType<T>::type IntervalType; 
00282   static const ShValueType IntervalValueType = __ShStorageToValueType<IntervalType>::type;
00283 
00284   static const char* name; 
00285 
00286   // @todo type include here the ability to set available operations 
00287 
00288   // @todo type include here ShPrograms for transforming from this
00289   // storage type to a set of different ones, allowing the transformers
00290   // to choose the best conversions.
00291 
00292   // once the above two things are complete, than user-defined types should
00293   // work just fine.
00294 };
00295 
00296 template<typename T>
00297 const char* ShStorageTypeInfo<T>::name = __ShStorageTypeName<T>::name;
00298 
00299 
00301 
00305 template<ShValueType V>
00306 struct ShValueTypeInfo: public ShStorageTypeInfo<typename __ShValueToStorageType<V>::type> {
00307 };
00308 
00309 }
00310 
00311 #include "ShStorageTypeImpl.hpp"
00312 
00313 #endif

Generated on Mon Jan 24 18:36:35 2005 for Sh by  doxygen 1.4.1