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

ShSwizzleImpl.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 SH_SWIZZLEIMPL_HPP
00028 #define SH_SWIZZLEIMPL_HPP
00029 #include <iostream>
00030 #include "ShSwizzle.hpp"
00031 #include "ShError.hpp"
00032 #include "ShDebug.hpp"
00033 
00034 namespace SH {
00035 
00036 inline ShSwizzle::ShSwizzle()
00037   : m_srcSize(0),
00038     m_size(0)
00039 {
00040   alloc();
00041 }
00042 
00043 inline ShSwizzle::ShSwizzle(int srcSize)
00044   : m_srcSize(srcSize),
00045     m_size(srcSize)
00046 {
00047   if(alloc()) {
00048     for(int i = 0; i < m_size; ++i) m_index.ptr[i] = i;
00049   } 
00050 }
00051 
00052 inline ShSwizzle::ShSwizzle(int srcSize, int i0)
00053   : m_srcSize(srcSize),
00054     m_size(1)
00055 {
00056   checkSrcSize(i0);
00057   if(alloc()) {
00058     m_index.ptr[0] = i0;
00059   } else {
00060     m_index.local[0] = (unsigned char)i0;
00061   }
00062 }
00063 
00064 inline ShSwizzle::ShSwizzle(int srcSize, int i0, int i1)
00065   : m_srcSize(srcSize),
00066     m_size(2)
00067 {
00068   checkSrcSize(i0);
00069   checkSrcSize(i1);
00070   if(alloc()) {
00071     m_index.ptr[0] = i0;
00072     m_index.ptr[1] = i1;
00073   } else {
00074     m_index.local[0] = (unsigned char)i0;
00075     m_index.local[1] = (unsigned char)i1;
00076   }
00077 }
00078 
00079 inline ShSwizzle::ShSwizzle(int srcSize, int i0, int i1, int i2)
00080   : m_srcSize(srcSize),
00081     m_size(3)
00082 {
00083   checkSrcSize(i0);
00084   checkSrcSize(i1);
00085   checkSrcSize(i2);
00086   if(alloc()) {
00087     m_index.ptr[0] = i0;
00088     m_index.ptr[1] = i1;
00089     m_index.ptr[2] = i2;
00090   } else {
00091     m_index.local[0] = (unsigned char)i0;
00092     m_index.local[1] = (unsigned char)i1;
00093     m_index.local[2] = (unsigned char)i2;
00094   }
00095 }
00096 
00097 inline ShSwizzle::ShSwizzle(int srcSize, int i0, int i1, int i2, int i3)
00098   : m_srcSize(srcSize),
00099     m_size(4)
00100 {
00101   checkSrcSize(i0);
00102   checkSrcSize(i1);
00103   checkSrcSize(i2);
00104   checkSrcSize(i3);
00105   if(alloc()) {
00106     m_index.ptr[0] = i0;
00107     m_index.ptr[1] = i1;
00108     m_index.ptr[2] = i2;
00109     m_index.ptr[3] = i3;
00110   } else {
00111     m_index.local[0] = (unsigned char)i0;
00112     m_index.local[1] = (unsigned char)i1;
00113     m_index.local[2] = (unsigned char)i2;
00114     m_index.local[3] = (unsigned char)i3;
00115   }
00116 }
00117 
00118 inline ShSwizzle::ShSwizzle(int srcSize, int size, int* indices)
00119   : m_srcSize(srcSize),
00120     m_size(size)
00121 {
00122   int i;
00123   for (i = 0; i < size; i++) checkSrcSize(indices[i]);
00124   if(alloc()) {
00125     for (i = 0; i < size; i++) m_index.ptr[i] = indices[i];
00126   } else {
00127     for (i = 0; i < size; i++) m_index.local[i] = (unsigned char)indices[i];
00128   }
00129 }
00130 
00131 
00132 inline ShSwizzle::ShSwizzle(const ShSwizzle& other)
00133   : m_srcSize(other.m_srcSize),
00134     m_size(other.m_size)
00135 {
00136   copy(other, !alloc());
00137 }
00138 
00139 inline ShSwizzle::~ShSwizzle()
00140 {
00141   dealloc();
00142 }
00143 
00144 inline ShSwizzle& ShSwizzle::operator=(const ShSwizzle& other)
00145 {
00146   if(this == &other) return *this;
00147 
00148   if(m_size != other.m_size || m_srcSize != other.m_srcSize) {
00149     dealloc();
00150     m_size = other.m_size;
00151     m_srcSize = other.m_srcSize;
00152     alloc();
00153   } 
00154   copy(other, local());
00155   return *this;
00156 }
00157 
00158 inline ShSwizzle& ShSwizzle::operator*=(const ShSwizzle& other)  
00159 {
00160   (*this) = (*this) * other;
00161   return (*this);
00162 }
00163 
00164 inline ShSwizzle ShSwizzle::operator*(const ShSwizzle& other) const
00165 {
00166   ShSwizzle result;
00167   result.m_size = other.m_size;
00168   result.m_srcSize = m_srcSize;
00169   bool resultLocal = true; 
00170   if(m_srcSize >= 256 || other.m_size > 4) { // result must go ptr 
00171     result.alloc();
00172     resultLocal = false;
00173   } 
00174 
00175   const bool isLocal = local();
00176   for (int i = 0; i < other.m_size; i++) {
00177     int oi = other[i];
00178     if (oi >= m_size) shError( ShSwizzleException(*this, oi, size()) );
00179     int index = isLocal ? m_index.local[oi] : m_index.ptr[oi];
00180     if(resultLocal) result.m_index.local[i] = index;
00181     else result.m_index.ptr[i] = index;
00182   }
00183   return result;
00184 }
00185 
00186 inline int ShSwizzle::operator[](int index) const
00187 {
00188   if (index >= m_size || index < 0) shError( ShSwizzleException(*this, index, m_size) );
00189   if(local()) return m_index.local[index];
00190   return m_index.ptr[index];
00191 }
00192 
00193 inline void ShSwizzle::copy(const ShSwizzle &other, bool islocal) 
00194 {
00195   if(islocal) {
00196     m_index.intval = other.m_index.intval;
00197   } else {
00198     memcpy(m_index.ptr, other.m_index.ptr, sizeof(int)*m_size);
00199   }
00200 }
00201 
00202 inline void ShSwizzle::checkSrcSize(int index) 
00203 {
00204   if (index < 0 || index >= m_srcSize) {
00205     shError( ShSwizzleException(*this, index, m_srcSize) );
00206   }
00207 }
00208 
00209 inline bool ShSwizzle::alloc()
00210 {
00211   if(local()) {
00212     m_index.intval = idswiz(); 
00213     return false; 
00214   } 
00215   m_index.ptr = new int[m_size];
00216   return true;
00217 }
00218 
00219 inline void ShSwizzle::dealloc()
00220 {
00221   if(!local()) delete [] m_index.ptr;
00222 }
00223 
00224 inline bool ShSwizzle::local() const
00225 {
00226   return (m_srcSize < 256 && m_size <= 4); 
00227 }
00228 
00229 inline int ShSwizzle::idswiz() const
00230 {
00231 // @todo type detect endianess correctly
00232 // mac's are not the only big endian machines...
00233 #ifdef __MAC__
00234   return 0x00010203;
00235 #else
00236   return 0x03020100;
00237 #endif
00238 }
00239 
00240 inline bool ShSwizzle::identity() const
00241 {
00242   if (m_size != m_srcSize) return false;
00243   if (local()) {
00244     // @todo type this is probably not portable...
00245     return m_index.intval == idswiz(); 
00246   } 
00247   for(int i = 0; i < m_size; ++i) {
00248     if(m_index.ptr[i] != i) return false;
00249   }
00250   return true; 
00251 }
00252 
00253 inline bool ShSwizzle::operator==(const ShSwizzle& other) const
00254 {
00255   if (m_srcSize != other.m_srcSize) return false;
00256   if (m_size != other.m_size) return false;
00257   if (local()) return m_index.intval == other.m_index.intval;
00258   return memcmp(m_index.ptr, other.m_index.ptr, sizeof(int)*m_size) == 0;
00259 }
00260 
00261 } // namespace SH
00262 
00263 #endif

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