#ifndef __cxz_urange_cc_h__ #define __cxz_urange_cc_h__ #include #include #include "urange.h" #include "xpr/for.h" namespace CNORXZ { /***************** * UIndex * *****************/ template UIndex::UIndex(const RangePtr& range, SizeT pos) : IndexInterface,MetaType>(pos), mRangePtr(rangeCast(range)), mMetaPtr(&mRangePtr->get(0)) {} template UIndex& UIndex::operator=(size_t pos) { IB::mPos = pos; return *this; } template UIndex& UIndex::operator++() { ++IB::mPos; return *this; } template UIndex& UIndex::operator--() { --IB::mPos; return *this; } template UIndex UIndex::operator+(Int n) const { return UIndex(mRangePtr, IB::mPos + n); } template UIndex UIndex::operator-(Int n) const { return UIndex(mRangePtr, IB::mPos - n); } template UIndex& UIndex::operator+=(Int n) { IB::mPos += n; return *this; } template UIndex& UIndex::operator-=(Int n) { IB::mPos -= n; return *this; } template SizeT UIndex::max() const { return mRangePtr->size(); } template IndexId<0> UIndex::id() const { return IndexId<0>(this->ptrId()); } template const MetaType& UIndex::operator*() const { return mMetaPtr[IB::mPos]; } template const MetaType* UIndex::operator->() const { return mMetaPtr + IB::mPos; } template Int UIndex::pp(PtrId idxPtrNum) { ++(*this); return 1; } template Int UIndex::mm(PtrId idxPtrNum) { --(*this); return 1; } template String UIndex::stringMeta() const { return toString(this->meta()); } template const MetaType& UIndex::meta() const { return mMetaPtr[IB::mPos]; } template UIndex& UIndex::at(const MetaType& metaPos) { (*this) = mRangePtr->getMeta(metaPos); return *this; } template size_t UIndex::dim() const // = 1 { return 1; } template Sptr> UIndex::range() const { return mRangePtr; } template template UPos UIndex::stepSize(const IndexId& id) const { return UPos(id == this->id() ? 1 : 0); } template template decltype(auto) UIndex::ifor(const PosT step, Xpr xpr) const { return For<0,PosT,Xpr>(this->max(), this->id(), step, xpr); } /********************** * URangeFactory * **********************/ template URangeFactory::URangeFactory(const Vector& space) : mSpace(space) {} template URangeFactory::URangeFactory(Vector&& space) : mSpace(space) {} template URangeFactory::URangeFactory(const Vector& space, const RangePtr& ref) : mSpace(space), mRef(ref) {} template URangeFactory::URangeFactory(Vector&& space, const RangePtr& ref) : mSpace(space), mRef(ref) {} template void URangeFactory::make() { auto info = typeid(URange); if(mRef != nullptr) { mProd = this->fromCreated[info.hash_code()][mRef->id()]; } if(mProd == nullptr){ RangePtr key = mProd = std::shared_ptr> ( new URange( std::move(mSpace) ) ); if(mRef != nullptr) { key = mRef; } this->addToCreated(info, { key->id() }, mProd); } } /*************** * URange * ***************/ template URange::URange(const Vector& space) : RangeInterface,MetaType>(), mSpace(space) { std::sort(mSpace.begin(), mSpace.end(), std::less()); auto itdupl = std::adjacent_find(mSpace.begin(), mSpace.end()); CXZ_ASSERT(itdupl == mSpace.end(), "found duplicate: " << *itdupl); } template URange::URange(Vector&& space) : RangeInterface,MetaType>(), mSpace(space) { std::sort(mSpace.begin(), mSpace.end(), std::less()); auto itdupl = std::adjacent_find(mSpace.begin(), mSpace.end()); CXZ_ASSERT(itdupl == mSpace.end(), "found duplicate: " << *itdupl); } template const MetaType& URange::get(SizeT pos) const { return mSpace[pos]; } template SizeT URange::getMeta(const MetaType& meta) const { auto b = mSpace.begin(); auto e = mSpace.end(); return std::lower_bound(b, e, meta, std::less()) - b; } template SizeT URange::size() const { return mSpace.size(); } template SizeT URange::dim() const { return 1; } template String URange::stringMeta(SizeT pos) const { return toString(this->get(pos)); } template typename URange::IndexType URange::begin() const { UIndex i( std::dynamic_pointer_cast > ( RangePtr( RB::mThis ) ) ); i = 0; return i; } template typename URange::IndexType URange::end() const { UIndex i( std::dynamic_pointer_cast > ( RangePtr( RB::mThis ) ) ); i = this->size(); return i; } /******************* * Range Casts * *******************/ template Sptr> RangeCast>::func(const RangePtr& r) { CXZ_ERROR("to be implemented..."); return nullptr; } } #endif