00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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) {
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
00232
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
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 }
00262
00263 #endif