#ifndef __functional_multi_array__ #define __functional_multi_array__ #include "multi_array_base.h" #include "slice.h" namespace MultiArrayTools { template struct ToMAObject { template static auto mk(const std::shared_ptr& i) -> MultiArray { std::vector vv(i->range()->size()); for(Index j = (*i); j.pos() != j.max(); ++j){ vv[j.pos()] = j.meta(); } return MultiArray( i->range(), vv ); } }; template <> struct ToMAObject { template static auto mk(const std::shared_ptr& i) -> ConstSlice { return ConstSlice( i->range(), i->metaPtr() ); } }; template auto mkMAObject(const std::shared_ptr& i) -> std::shared_ptr::mk(i))> { return std::make_shared::mk(i))> (ToMAObject::mk(i)); } /* template struct ToOpObject { template static auto mk(const std::shared_ptr& ind) -> MetaOperationRoot { typedef typename Index::RangeType RangeType; MultiRangeFactory mrf(ind->range()); auto mr = std::dynamic_pointer_cast( mrf.create() ); typedef typename MultiRange::IndexType::MetaType value_type; ContainerIndex ci(mr,0); return MetaOperationRoot(ci); } }; template <> struct ToOpObject { template static auto mk(const std::shared_ptr& ind) -> ConstOperationRoot { return ConstOperationRoot( mkMAObject(ind), ind); } }; */ template struct ToOpObject { template static auto mk(const std::shared_ptr& ind) -> ConstOperationRoot { return ConstOperationRoot( mkMAObject(ind), ind); } }; template auto mkOpObject(const std::shared_ptr& i) -> decltype(ToOpObject::mk(i)) { return ToOpObject::mk(i); } template class FunctionalMultiArray : public MultiArrayBase { public: typedef ContainerRange CRange; typedef MultiArrayBase MAB; //typedef typename MultiArrayBase::const_iterator const_iterator; typedef ContainerIndex IndexType; //typedef typename CRange::IndexType IndexType; typedef MultiArray MAType; typedef T value_type; private: mutable T mVal; std::shared_ptr mFunc; mutable std::shared_ptr mMaPtr; public: DEFAULT_MEMBERS(FunctionalMultiArray); FunctionalMultiArray(const std::shared_ptr&... ranges, const std::shared_ptr& func); FunctionalMultiArray(const std::shared_ptr&... ranges); FunctionalMultiArray(const typename CRange::Space& space); FunctionalMultiArray(const typename CRange::Space& space, const std::shared_ptr& func); virtual const T& operator[](const IndexType& i) const override; virtual const T& at(const typename CRange::IndexType::MetaType& meta) const override; virtual const T* data() const override; virtual bool isConst() const override; virtual bool isSlice() const override; virtual std::shared_ptr > anonymous(bool slice = false) const override; // EVALUTAION CLASS ??!!!! auto exec(const std::shared_ptr&... inds) const // -> decltype( mkOperation( mFunc, ConstOperationRoot( mkMAObject( inds ), inds) ... ) ); -> decltype( mkOperation( mFunc, mkOpObject(inds) ... ) ); virtual ConstOperationRoot operator()(const std::shared_ptr&... inds) const override; }; } // namespace MultiArrayTools /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace MultiArrayTools { /**************************** * FunctionalMultiArray * ****************************/ /* template FunctionalMultiArray::FunctionalMultiArray(const Range& range) : MultiArrayBase(range), mFunc() {} */ template struct Application { template static inline T apply(const std::shared_ptr& f, const Meta& m) { return (*f)(m); } }; template <> struct Application { template static inline T apply(const std::shared_ptr& f, const Meta& m) { return Function::apply(m); } }; template FunctionalMultiArray::FunctionalMultiArray(const std::shared_ptr&... ranges, const std::shared_ptr& func) : MultiArrayBase(ranges...), mFunc(func) {} template FunctionalMultiArray::FunctionalMultiArray(const std::shared_ptr&... ranges) : MultiArrayBase(ranges...) {} template FunctionalMultiArray::FunctionalMultiArray(const typename CRange::Space& space) : MultiArrayBase(space) {} template FunctionalMultiArray::FunctionalMultiArray(const typename CRange::Space& space, const std::shared_ptr& func) : MultiArrayBase(space), mFunc(func) {} template const T& FunctionalMultiArray::operator[](const IndexType& i) const { mVal = Application::template apply(mFunc, i.meta()); return mVal; } template const T& FunctionalMultiArray::at(const typename CRange::IndexType::MetaType& meta) const { mVal = Application::template apply(mFunc,meta); return mVal; } template const T* FunctionalMultiArray::data() const { return &mVal; } template bool FunctionalMultiArray::isConst() const { return true; } template bool FunctionalMultiArray::isSlice() const { return false; } template std::shared_ptr > FunctionalMultiArray::anonymous(bool slice) const { assert(0); // think about it carefully return nullptr; } template ConstOperationRoot FunctionalMultiArray:: operator()(const std::shared_ptr&... inds) const { if(not mMaPtr){ mMaPtr = std::make_shared( MAB::mRange->space() ); (*mMaPtr)(inds...) = exec(inds...); } return ConstOperationRoot( *mMaPtr, inds... ); } /* template auto FunctionalMultiArray:: exec(const std::shared_ptr&... inds) const -> decltype( mkOperation( mFunc, ConstOperationRoot( mkMAObject( inds ), inds) ... ) ) { return mkOperation( mFunc, ConstOperationRoot( mkMAObject( inds ), inds ) ... ); } */ template auto FunctionalMultiArray:: exec(const std::shared_ptr&... inds) const -> decltype( mkOperation( mFunc, mkOpObject(inds) ... ) ) { return mkOperation( mFunc, mkOpObject(inds) ... ); } } // namespace MultiArrayTools #endif