TypedArray.hpp

00001 #ifndef __FIBER_TYPEDARRAY_HPP
00002 #define __FIBER_TYPEDARRAY_HPP
00003 
00004 #include "MemBase.hpp"
00005 #include <memcore/Chunk.hpp>
00006 
00007 namespace Fiber
00008 {
00009 
00010 template <int N, class T>
00011         class   MemArray;
00012 
00013 
00028 template <class T>
00029         class TypedArray : virtual public MemBase
00030 {
00031 public:
00033         typedef T       value_type;
00034 
00036         TypedArray(const MemBase::Creator_t&C)
00037         : MemBase(C)
00038         {}
00039 
00041         virtual T first() const = 0;
00042 
00044         virtual T last()  const = 0;
00045 
00046         virtual CreativeIterator<T>* creativeIterator() = 0;
00047 
00048         virtual const CreativeIterator<T>* creativeIterator() const = 0;
00049 
00053         virtual RefPtr<MemCore::TypedChunk<T> > myChunk() const = 0;
00054 
00055 
00056         override RefPtr<MemCore::ChunkBase> getChunk() const
00057         {
00058                 return myChunk();
00059         }
00060 
00061 
00062 static  RefPtr<MemBase> create(const RefPtr<MemBase>&SourceLayout,
00063                                const MemBase::Creator_t&C = MemCore::NullPtr(),
00064                                const type_info&layout = typeid(void) )
00065         {
00066                 return SourceLayout->create( FiberType<T>::getFiberType().self(), C, layout);
00067         }
00068 
00077         template <class UnaryOperator>
00078         RefPtr<MemBase> applyOperator(const UnaryOperator&theOperator, const MemBase::Creator_t&theCreator) const
00079         {
00080         const CreativeIterator<T>*C = creativeIterator();
00081                 if (!C)
00082                         return MemCore::NullPtr();
00083 
00084         const CreativeIterator<T>&CI = *C; 
00085         const Iterator<T>&It = CI;
00086 
00087         MemCore::MemVector<T> Result( CI.count() );
00088                 for(index_t i=0; i<It.count(); i++)
00089                 {
00090                 const   T&in  = It[i];
00091                         T&out = Result[i];
00092                         out   = theOperator( in );
00093                 }
00094                 return createEquallySizedMemArray( Result, theCreator);
00095         }
00096 
00103         template <class BinaryOperator>
00104         RefPtr<MemBase> applyOperator(const BinaryOperator&theOperator, const RefPtr<MemBase>&rightValue, const MemBase::Creator_t&theCreator) const
00105         {
00106         const CreativeIterator<T>*C = creativeIterator();
00107                 if (!C)
00108                         return MemCore::NullPtr();
00109 
00110         RefPtr<TypedArray> RightMemArray = rightValue;
00111                 if (!RightMemArray)
00112                         return MemCore::NullPtr();
00113 
00114         const CreativeIterator<T>*CR = RightMemArray->creativeIterator();
00115                 if (!CR)
00116                         return MemCore::NullPtr();
00117 
00118         const CreativeIterator<T>&CI = *C;
00119         const CreativeIterator<T>& R = *CR;
00120 
00121                 if (CI.count() != R.count() )
00122                         return MemCore::NullPtr();
00123 
00124         MemCore::MemVector<T> Result( CI.count() );
00125                 for(index_t i=0; i<CI.count(); i++)
00126                 {
00127                 const   T&in  = C[i];
00128                 const   T&inR = R[i];
00129                         T&out = Result[i];
00130                         out   = theOperator( in, inR );
00131                 }
00132                 return createEquallySizedMemArray( Result, theCreator);
00133         }
00134 
00135         
00137         override RefPtr<MemBase> createIndirection(const DynamicSize&newSize, const std::vector<index_t>&Indirection, const MemBase::Creator_t&theCreator) const
00138         {
00139                 if (Indirection.size() != newSize.nElements() )
00140                         return MemCore::NullPtr();
00141 
00142         const CreativeIterator<T>*C = creativeIterator();
00143                 if (!C)
00144                         return MemCore::NullPtr();
00145 
00146         const CreativeIterator<T>&CI = *C;
00147         const Iterator<T>&It = CI;
00148 
00149         RefPtr<MemBase> newData = this->newMemArray(newSize, theCreator); 
00150                 if (!newData)
00151                         return MemCore::NullPtr();
00152 
00153         RefPtr<TypedArray> dst = newData; 
00154                 if (!dst)
00155                         return MemCore::NullPtr();
00156 
00157         const CreativeIterator<T>*Cdst = dst->creativeIterator(); 
00158                 if (!Cdst)
00159                         return MemCore::NullPtr();
00160 
00161         const CreativeIterator<T>&CIdst = *Cdst;
00162         const Iterator<T>&Itdst = CIdst;
00163 
00164         index_t nElements = Indirection.size();
00165                 for(index_t i=0; i<nElements; i++)
00166                 {
00167                 index_t src_index = Indirection[ i ];
00168 
00169                         Itdst[i] = It[ src_index ];
00170                 }
00171 
00172                 return newData;
00173         }
00174 
00175 };
00176 
00177 /* @ingroup field
00178    A convenience class that behaves like a (strong) reference to a TypedArray,
00179    but is more critical, in that it appears to be valid only if this TypedArray
00180    may provide a CreativeIterator.
00181 
00182    @author Werner Benger
00183  */
00184 template <class T>
00185         class TypedIterator
00186 {
00187         RefPtr<TypedArray<T> > SRC;
00188 public:
00189 
00191         TypedIterator()
00192         {}
00193 
00195         TypedIterator(const RefPtr<MemBase>&src)
00196         : SRC(src)
00197         {}
00198 
00200         TypedIterator(const RefPtr<TypedArray<T> >&src)
00201         : SRC(src)
00202         {}
00203 
00205         bool operator=(const RefPtr<MemBase>&src)
00206         {
00207                 SRC = src; 
00208                 if (SRC) return true; 
00209                 else     return false;
00210         }
00211 
00213         bool operator=(const RefPtr<TypedArray<T> >&src)
00214         {
00215                 SRC = src; 
00216                 if (SRC) return true; 
00217                 else     return false;
00218         }
00219 
00221         template <int N>
00222         bool operator=(const RefPtr<MemArray<N, T> >&src)
00223         {
00224                 SRC = src; 
00225                 if (SRC) return true; 
00226                 else     return false;
00227         }
00228 
00233         operator bool() const
00234         {
00235                 if (!SRC)
00236                         return false;
00237 
00238         CreativeIterator<T>*C = SRC ->creativeIterator(); 
00239                 if (!C)
00240                         return false; 
00241 
00242                 return true; 
00243         }
00244 
00248         const RefPtr<TypedArray<T> >&operator()() const
00249         {
00250                 return SRC;
00251         }
00252 
00260         CreativeIterator<T>&operator*() const
00261         {
00262                 assert(SRC);
00263 
00264         CreativeIterator<T>*C = SRC ->creativeIterator();
00265                 assert( C );
00266                 return *C;
00267         }
00268 };
00269 
00270 } // namespace Fiber
00271 
00272 #endif /* __FIBER_TYPEDARRAY_HPP */
00273