00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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) {
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
00229
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
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 }
00259
00260 #endif