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

ShVariantImpl.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 SHVARIANT_IMPL_HPP
00028 #define SHVARIANT_IMPL_HPP
00029 
00030 #include <algorithm>
00031 #include <sstream>
00032 #include "ShDebug.hpp"
00033 #include "ShError.hpp"
00034 #include "ShCastManager.hpp"
00035 #include "ShVariant.hpp"
00036 #include "ShTypeInfo.hpp"
00037 #include "ShInterval.hpp"
00038 
00039 namespace SH {
00040 
00041 #ifdef SH_USE_MEMORY_POOL
00042 template<typename T, ShDataType DT>
00043 ShPool* ShDataVariant<T, DT>::m_pool = 0;
00044 #endif
00045 
00046 template<typename T, ShDataType DT>
00047 ShDataVariant<T, DT>::ShDataVariant(int N)
00048   : m_managed(true)
00049 {
00050   alloc(N);
00051   std::fill(m_begin, m_end, ShDataTypeConstant<T, DT>::Zero);
00052 }
00053 
00054 template<typename T, ShDataType DT>
00055 ShDataVariant<T, DT>::ShDataVariant(int N, const DataType &value)
00056   : m_managed(true)
00057 {
00058   alloc(N);
00059   std::fill(m_begin, m_end, value); 
00060 }
00061 
00062 template<typename T, ShDataType DT>
00063 ShDataVariant<T, DT>::ShDataVariant(std::string encodedValue) 
00064   : m_managed(true)
00065 {
00066   std::istringstream in(encodedValue);
00067 
00068   int size;
00069   in >> size;
00070   alloc(size);
00071 
00072   for(iterator I = m_begin; I != m_end; ++I) {
00073     in.ignore(1, '$');
00074     in >> (*I); 
00075   }
00076 }
00077 
00078 template<typename T, ShDataType DT>
00079 ShDataVariant<T, DT>::ShDataVariant(void *data, int N, bool managed)
00080   : m_managed(managed)
00081 {
00082   if(m_managed) {
00083     alloc(N);
00084     memcpy(m_begin, data, N * datasize());
00085   } else {
00086     m_begin = reinterpret_cast<DataType*>(data);
00087     m_end = m_begin + N;
00088   }
00089 }
00090 
00091 template<typename T, ShDataType DT>
00092 ShDataVariant<T, DT>::ShDataVariant(const ShDataVariant<T, DT> &other)
00093   : m_managed(true)
00094 {
00095   int size = other.size();
00096   alloc(size);
00097   memcpy(m_begin, other.m_begin, size * datasize());
00098 }
00099 
00100 template<typename T, ShDataType DT>
00101 ShDataVariant<T, DT>::ShDataVariant(const ShDataVariant<T, DT> &other, 
00102     bool neg, const ShSwizzle &swizzle)
00103   : m_managed(true)
00104 {
00105   alloc(swizzle.size());
00106   for(int i = 0; i < swizzle.size(); ++i) {
00107     m_begin[i] = other[swizzle[i]];
00108   }
00109   if(neg) negate();
00110 }
00111 
00112 template<typename T, ShDataType DT>
00113 ShDataVariant<T, DT>::~ShDataVariant() 
00114 {
00115   if(m_managed) delete m_begin;
00116 }
00117 
00118 template<typename T, ShDataType DT>
00119 ShValueType ShDataVariant<T, DT>::valueType() const {
00120   return value_type; 
00121 }
00122 
00123 template<typename T, ShDataType DT>
00124 ShDataType ShDataVariant<T, DT>::dataType() const {
00125   return DT; 
00126 }
00127 
00128 template<typename T, ShDataType DT>
00129 bool ShDataVariant<T, DT>::typeMatches(
00130     ShValueType valueType, ShDataType dataType) const {
00131   return (valueType == value_type) && (dataType == DT);
00132 }
00133 
00134 
00135 template<typename T, ShDataType DT>
00136 const char* ShDataVariant<T, DT>::typeName() const {
00137   return ShStorageTypeInfo<T>::name;
00138 }
00139 
00140 template<typename T, ShDataType DT>
00141 int ShDataVariant<T, DT>::size() const
00142 {
00143   return m_end - m_begin; 
00144 }
00145 
00146 template<typename T, ShDataType DT>
00147 int ShDataVariant<T, DT>::datasize() const
00148 {
00149   return sizeof(DataType); 
00150 }
00151 
00152 template<typename T, ShDataType DT>
00153 bool ShDataVariant<T, DT>::managed() const
00154 {
00155   return m_managed; 
00156 }
00157 
00158 template<typename T, ShDataType DT>
00159 void ShDataVariant<T, DT>::negate()
00160 {
00161   transform(m_begin, m_end, m_begin, std::negate<DataType>());
00162 }
00163 
00164 template<typename T, ShDataType DT>
00165 void ShDataVariant<T, DT>::set(const ShVariant* other)
00166 {
00167   SH_DEBUG_ASSERT(other->size() == size());
00168   ShCastManager::instance()->doCast(this, other);
00169 }
00170 
00171 template<typename T, ShDataType DT>
00172 void ShDataVariant<T, DT>::set(ShVariantCPtr other)
00173 {
00174   set(other.object());
00175 }
00176 
00177 template<typename T, ShDataType DT>
00178 void ShDataVariant<T, DT>::set(const ShVariant* other, int index)
00179 {
00180   SH_DEBUG_ASSERT(other->size() == 1); 
00181   // make a new DataVariant that uses the index element as it's array 
00182   ShDataVariant *temp = new ShDataVariant(m_begin + index, 1, false);
00183   ShCastManager::instance()->doCast(temp, other);
00184   delete temp; // okay - it doesn't delete its array
00185 }
00186 
00187 template<typename T, ShDataType DT>
00188 void ShDataVariant<T, DT>::set(ShVariantCPtr other, int index)
00189 {
00190   set(other.object(), index);
00191 }
00192 
00193 template<typename T, ShDataType DT>
00194 void ShDataVariant<T, DT>::set(const ShVariant* other, bool neg, const ShSwizzle &writemask) 
00195 {
00196   int wmsize = writemask.size();
00197   SH_DEBUG_ASSERT(wmsize == other->size());
00198   if(writemask.identity() && (wmsize == size())) {
00199     set(other);
00200     if(neg) negate();
00201     return;
00202   }
00203 
00204   // otherwise we need a temp buffer variant...doh
00205   ShDataVariant *temp = new ShDataVariant(wmsize);
00206   ShCastManager::instance()->doCast(temp, other);
00207   for(int i = 0; i < wmsize; ++i) {
00208     m_begin[writemask[i]] = neg ? -(*temp)[i] : (*temp)[i];
00209   }
00210   delete temp;
00211 }
00212 
00213 template<typename T, ShDataType DT>
00214 void ShDataVariant<T, DT>::set(ShVariantCPtr other, bool neg, const ShSwizzle &writemask) 
00215 {
00216   set(other.object(), neg, writemask);
00217 }
00218 
00219 template<typename T, ShDataType DT>
00220 ShVariantPtr ShDataVariant<T, DT>::get() const
00221 {
00222   return new ShDataVariant<T, DT>(*this);
00223 }
00224 
00225 template<typename T, ShDataType DT>
00226 ShVariantPtr ShDataVariant<T, DT>::get(int index) const
00227 {
00228   return new ShDataVariant<T, DT>(1, m_begin[index]);
00229 }
00230 
00231 template<typename T, ShDataType DT>
00232 ShVariantPtr ShDataVariant<T, DT>::get(bool neg, const ShSwizzle &swizzle) const 
00233 {
00234   return new ShDataVariant<T, DT>(*this, neg, swizzle);
00235 }
00236 
00237 
00238 template<typename T, ShDataType DT>
00239 bool ShDataVariant<T, DT>::equals(const ShVariant* other) const 
00240 {
00241   if(!other || (size() != other->size()) 
00242       || !other->typeMatches(valueType(), dataType())) return false;
00243 
00244   const ShDataVariant* castOther = variant_cast<T, DT>(other);
00245   const_iterator I, J;
00246   I = m_begin; 
00247   J = castOther->begin(); 
00248   for(;I != m_end; ++I, ++J) {
00249     if(!shDataTypeEqual((*I), (*J))) return false;
00250   }
00251   return true;
00252 }
00253 
00254 template<typename T, ShDataType DT>
00255 bool ShDataVariant<T, DT>::equals(ShVariantCPtr other) const 
00256 {
00257   return equals(other.object());
00258 }
00259 
00260 template<typename T, ShDataType DT>
00261 bool ShDataVariant<T, DT>::isTrue() const 
00262 {
00263   for(const_iterator I = begin(); I != end(); ++I) {
00264     if(!shDataTypeIsPositive((*I))) return false;
00265   }
00266   return true;
00267 }
00268 
00269 template<typename T, ShDataType DT>
00270 void* ShDataVariant<T, DT>::array()
00271 {
00272   return m_begin;
00273 }
00274 
00275 template<typename T, ShDataType DT>
00276 const void* ShDataVariant<T, DT>::array() const
00277 {
00278   return m_begin;
00279 }
00280 
00281 template<typename T, ShDataType DT>
00282 typename ShDataVariant<T, DT>::DataType& ShDataVariant<T, DT>::operator[](int index) 
00283 {
00284   return m_begin[index];
00285 }
00286 
00287 template<typename T, ShDataType DT>
00288 const typename ShDataVariant<T, DT>::DataType& ShDataVariant<T, DT>::operator[](int index) const
00289 {
00290   return m_begin[index];
00291 }
00292 
00293 template<typename T, ShDataType DT>
00294 typename ShDataVariant<T, DT>::iterator ShDataVariant<T, DT>::begin() {
00295   return m_begin;
00296 }
00297 
00298 template<typename T, ShDataType DT>
00299 typename ShDataVariant<T, DT>::iterator ShDataVariant<T, DT>::end() {
00300   return m_end;
00301 }
00302 
00303 template<typename T, ShDataType DT>
00304 typename ShDataVariant<T, DT>::const_iterator ShDataVariant<T, DT>::begin() const {
00305   return m_begin;
00306 }
00307 
00308 template<typename T, ShDataType DT>
00309 typename ShDataVariant<T, DT>::const_iterator ShDataVariant<T, DT>::end() const {
00310   return m_end;
00311 }
00312 
00313 template<typename T, ShDataType DT>
00314 std::string ShDataVariant<T, DT>::encode() const {
00315   if(size() < 1) return "";
00316 
00317   std::ostringstream out;
00318   out << size(); 
00319   for(const_iterator I = m_begin; I != m_end; ++I) {
00320     out << "," << *I;
00321   }
00322   return out.str();
00323 }
00324 template<typename T, ShDataType DT>
00325 std::string ShDataVariant<T, DT>::encode(int index, int repeats) const 
00326 {
00327   std::ostringstream out;
00328   out << repeats;
00329   for(int i = 0; i < repeats; ++i) {
00330     out << ", " << m_begin[index];
00331   }
00332   return out.str();
00333 }
00334 
00335 template<typename T, ShDataType DT>
00336 std::string ShDataVariant<T, DT>::encode(bool neg, const ShSwizzle &swizzle) const 
00337 {
00338   std::ostringstream out;
00339   out << swizzle.size(); 
00340   for(int i = 0; i < swizzle.size(); ++i) {
00341     out << ", " << m_begin[swizzle[i]];
00342   }
00343   return out.str();
00344 }
00345 
00346 // @todo type do Interval types
00347 template<typename T, ShDataType DT>
00348 std::string ShDataVariant<T, DT>::encodeArray() const {
00349   if(size() < 1) return "";
00350 
00351   std::ostringstream out;
00352   for(const_iterator I = m_begin; I != m_end; ++I) {
00353     if(I != m_begin) out << ", ";
00354     out << *I;
00355   }
00356   return out.str();
00357 }
00358 
00359 template<typename T, ShDataType DT>
00360 void ShDataVariant<T, DT>::alloc(int N) {
00361   // SH_DEBUG_PRINT("alloc " << valueTypeName[V] << " " << dataTypeName[DT]);
00362   m_begin = new DataType[N];
00363   m_end = m_begin + N;
00364 }
00365 
00366 #ifdef SH_USE_MEMORY_POOL
00367 template<typename T, ShDataType DT>
00368 void* ShDataVariant<T, DT>::operator new(std::size_t size)
00369 {
00370   if (size != sizeof(ShDataVariant)) return ::operator new(size);
00371   if (!m_pool) {
00372     m_pool = new ShPool(sizeof(ShDataVariant), 32768);
00373   }
00374   return m_pool->alloc();
00375 }
00376 
00377 template<typename T, ShDataType DT>
00378 void ShDataVariant<T, DT>::operator delete(void* ptr, std::size_t size)
00379 {
00380   if(size != sizeof(ShDataVariant)) {
00381     SH_DEBUG_PRINT("delete size does not match " << size << " " << sizeof(ShDataVariant));
00382   }
00383   if(!m_pool) shError( ShException( "Deleting from memory pool without an m_pool." ) );
00384   m_pool->free(ptr);
00385 }
00386 #endif
00387 
00388 template<typename T, ShDataType DT>
00389 ShPointer<ShDataVariant<T, DT> > variant_cast(ShVariantPtr c)
00390 {
00391   return shref_dynamic_cast<ShDataVariant<T, DT> >(c);
00392 }
00393 
00394 template<typename T, ShDataType DT>
00395 ShPointer<const ShDataVariant<T, DT> > variant_cast(ShVariantCPtr c)
00396 {
00397   return shref_dynamic_cast<const ShDataVariant<T, DT> >(c);
00398 }
00399 
00400 template<typename T, ShDataType DT>
00401 ShDataVariant<T, DT>* variant_cast(ShVariant* c)
00402 {
00403   return dynamic_cast<ShDataVariant<T, DT>*>(c);
00404 }
00405 
00406 template<typename T, ShDataType DT>
00407 const ShDataVariant<T, DT>* variant_cast(const ShVariant* c)
00408 {
00409   return dynamic_cast<const ShDataVariant<T, DT>*>(c);
00410 }
00411 
00412 template<typename T, ShDataType DT>
00413 ShPointer<ShDataVariant<T, DT> > variant_convert(ShVariantCPtr c)
00414 {
00415   ShDataVariant<T, DT>* result = new ShDataVariant<T, DT>(c->size());
00416   ShCastManager::instance()->doCast(result, c.object());
00417   return result;
00418 }
00419 
00420 }
00421 #endif

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