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 2003-2005 Serious Hack Inc.
00004 // 
00005 // This software is provided 'as-is', without any express or implied
00006 // warranty. In no event will the authors be held liable for any damages
00007 // arising from the use of this software.
00008 // 
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it
00011 // freely, subject to the following restrictions:
00012 // 
00013 // 1. The origin of this software must not be misrepresented; you must
00014 // not claim that you wrote the original software. If you use this
00015 // software in a product, an acknowledgment in the product documentation
00016 // would be appreciated but is not required.
00017 // 
00018 // 2. Altered source versions must be plainly marked as such, and must
00019 // not be misrepresented as being the original software.
00020 // 
00021 // 3. This notice may not be removed or altered from any source
00022 // distribution.
00024 #ifndef SH_SWIZZLEIMPL_HPP
00025 #define SH_SWIZZLEIMPL_HPP
00026 #include <iostream>
00027 #include "ShSwizzle.hpp"
00028 #include "ShError.hpp"
00029 #include "ShDebug.hpp"
00030 
00031 namespace SH {
00032 
00033 inline ShSwizzle::ShSwizzle()
00034   : m_srcSize(0),
00035     m_size(0)
00036 {
00037   alloc();
00038 }
00039 
00040 inline ShSwizzle::ShSwizzle(int srcSize)
00041   : m_srcSize(srcSize),
00042     m_size(srcSize)
00043 {
00044   if(alloc()) {
00045     for(int i = 0; i < m_size; ++i) m_index.ptr[i] = i;
00046   } 
00047 }
00048 
00049 inline ShSwizzle::ShSwizzle(int srcSize, int i0)
00050   : m_srcSize(srcSize),
00051     m_size(1)
00052 {
00053   checkSrcSize(i0);
00054   if(alloc()) {
00055     m_index.ptr[0] = i0;
00056   } else {
00057     m_index.local[0] = (unsigned char)i0;
00058   }
00059 }
00060 
00061 inline ShSwizzle::ShSwizzle(int srcSize, int i0, int i1)
00062   : m_srcSize(srcSize),
00063     m_size(2)
00064 {
00065   checkSrcSize(i0);
00066   checkSrcSize(i1);
00067   if(alloc()) {
00068     m_index.ptr[0] = i0;
00069     m_index.ptr[1] = i1;
00070   } else {
00071     m_index.local[0] = (unsigned char)i0;
00072     m_index.local[1] = (unsigned char)i1;
00073   }
00074 }
00075 
00076 inline ShSwizzle::ShSwizzle(int srcSize, int i0, int i1, int i2)
00077   : m_srcSize(srcSize),
00078     m_size(3)
00079 {
00080   checkSrcSize(i0);
00081   checkSrcSize(i1);
00082   checkSrcSize(i2);
00083   if(alloc()) {
00084     m_index.ptr[0] = i0;
00085     m_index.ptr[1] = i1;
00086     m_index.ptr[2] = i2;
00087   } else {
00088     m_index.local[0] = (unsigned char)i0;
00089     m_index.local[1] = (unsigned char)i1;
00090     m_index.local[2] = (unsigned char)i2;
00091   }
00092 }
00093 
00094 inline ShSwizzle::ShSwizzle(int srcSize, int i0, int i1, int i2, int i3)
00095   : m_srcSize(srcSize),
00096     m_size(4)
00097 {
00098   checkSrcSize(i0);
00099   checkSrcSize(i1);
00100   checkSrcSize(i2);
00101   checkSrcSize(i3);
00102   if(alloc()) {
00103     m_index.ptr[0] = i0;
00104     m_index.ptr[1] = i1;
00105     m_index.ptr[2] = i2;
00106     m_index.ptr[3] = i3;
00107   } else {
00108     m_index.local[0] = (unsigned char)i0;
00109     m_index.local[1] = (unsigned char)i1;
00110     m_index.local[2] = (unsigned char)i2;
00111     m_index.local[3] = (unsigned char)i3;
00112   }
00113 }
00114 
00115 inline ShSwizzle::ShSwizzle(int srcSize, int size, int* indices)
00116   : m_srcSize(srcSize),
00117     m_size(size)
00118 {
00119   int i;
00120   for (i = 0; i < size; i++) checkSrcSize(indices[i]);
00121   if(alloc()) {
00122     for (i = 0; i < size; i++) m_index.ptr[i] = indices[i];
00123   } else {
00124     for (i = 0; i < size; i++) m_index.local[i] = (unsigned char)indices[i];
00125   }
00126 }
00127 
00128 
00129 inline ShSwizzle::ShSwizzle(const ShSwizzle& other)
00130   : m_srcSize(other.m_srcSize),
00131     m_size(other.m_size)
00132 {
00133   copy(other, !alloc());
00134 }
00135 
00136 inline ShSwizzle::~ShSwizzle()
00137 {
00138   dealloc();
00139 }
00140 
00141 inline ShSwizzle& ShSwizzle::operator=(const ShSwizzle& other)
00142 {
00143   if(this == &other) return *this;
00144 
00145   if(m_size != other.m_size || m_srcSize != other.m_srcSize) {
00146     dealloc();
00147     m_size = other.m_size;
00148     m_srcSize = other.m_srcSize;
00149     alloc();
00150   } 
00151   copy(other, local());
00152   return *this;
00153 }
00154 
00155 inline ShSwizzle& ShSwizzle::operator*=(const ShSwizzle& other)  
00156 {
00157   (*this) = (*this) * other;
00158   return (*this);
00159 }
00160 
00161 inline ShSwizzle ShSwizzle::operator*(const ShSwizzle& other) const
00162 {
00163   ShSwizzle result;
00164   result.m_size = other.m_size;
00165   result.m_srcSize = m_srcSize;
00166   bool resultLocal = true; 
00167   if(m_srcSize >= 256 || other.m_size > 4) { // result must go ptr 
00168     result.alloc();
00169     resultLocal = false;
00170   } 
00171 
00172   const bool isLocal = local();
00173   for (int i = 0; i < other.m_size; i++) {
00174     int oi = other[i];
00175     if (oi >= m_size) shError( ShSwizzleException(*this, oi, size()) );
00176     int index = isLocal ? m_index.local[oi] : m_index.ptr[oi];
00177     if(resultLocal) result.m_index.local[i] = index;
00178     else result.m_index.ptr[i] = index;
00179   }
00180   return result;
00181 }
00182 
00183 inline int ShSwizzle::operator[](int index) const
00184 {
00185   if (index >= m_size || index < 0) shError( ShSwizzleException(*this, index, m_size) );
00186   if(local()) return m_index.local[index];
00187   return m_index.ptr[index];
00188 }
00189 
00190 inline void ShSwizzle::copy(const ShSwizzle &other, bool islocal) 
00191 {
00192   if(islocal) {
00193     m_index.intval = other.m_index.intval;
00194   } else {
00195     memcpy(m_index.ptr, other.m_index.ptr, sizeof(int)*m_size);
00196   }
00197 }
00198 
00199 inline void ShSwizzle::checkSrcSize(int index) 
00200 {
00201   if (index < 0 || index >= m_srcSize) {
00202     shError( ShSwizzleException(*this, index, m_srcSize) );
00203   }
00204 }
00205 
00206 inline bool ShSwizzle::alloc()
00207 {
00208   if(local()) {
00209     m_index.intval = idswiz(); 
00210     return false; 
00211   } 
00212   m_index.ptr = new int[m_size];
00213   return true;
00214 }
00215 
00216 inline void ShSwizzle::dealloc()
00217 {
00218   if(!local()) delete [] m_index.ptr;
00219 }
00220 
00221 inline bool ShSwizzle::local() const
00222 {
00223   return (m_srcSize < 256 && m_size <= 4); 
00224 }
00225 
00226 inline int ShSwizzle::idswiz() const
00227 {
00228 // @todo type detect endianess correctly
00229 // mac's are not the only big endian machines...
00230 #ifdef __APPLE__
00231   return 0x00010203;
00232 #else
00233   return 0x03020100;
00234 #endif
00235 }
00236 
00237 inline bool ShSwizzle::identity() const
00238 {
00239   if (m_size != m_srcSize) return false;
00240   if (local()) {
00241     // @todo type this is probably not portable...
00242     return m_index.intval == idswiz(); 
00243   } 
00244   for(int i = 0; i < m_size; ++i) {
00245     if(m_index.ptr[i] != i) return false;
00246   }
00247   return true; 
00248 }
00249 
00250 inline bool ShSwizzle::operator==(const ShSwizzle& other) const
00251 {
00252   if (m_srcSize != other.m_srcSize) return false;
00253   if (m_size != other.m_size) return false;
00254   if (local()) return m_index.intval == other.m_index.intval;
00255   return memcmp(m_index.ptr, other.m_index.ptr, sizeof(int)*m_size) == 0;
00256 }
00257 
00258 } // namespace SH
00259 
00260 #endif

Generated on Wed Jun 15 18:12:42 2005 for Sh by  doxygen 1.4.3-20050530