basically finish de-virtualization of indices; TODO: const THIS + 'incomplete type' issue + probably further (NOT COMPILABLE)

This commit is contained in:
Christian Zimmermann 2017-12-11 18:49:43 +01:00
parent defa568c5b
commit 888c7f6a07
8 changed files with 364 additions and 515 deletions

View file

@ -44,7 +44,7 @@ namespace MultiArrayTools
virtual IndexType begin() const override; virtual IndexType begin() const override;
virtual IndexType end() const override; virtual IndexType end() const override;
virtual std::shared_ptr<IndexBase> index() const override; virtual std::shared_ptr<VIWB> index() const override;
friend AnonymousRangeFactory; friend AnonymousRangeFactory;
@ -155,11 +155,12 @@ namespace MultiArrayTools
} }
// put this in the interface class !!! // put this in the interface class !!!
std::shared_ptr<IndexBase> AnonymousRange::index() const std::shared_ptr<VIWB> AnonymousRange::index() const
{ {
return std::make_shared<SingleIndex > return std::make_shared<VIWB>
( std::dynamic_pointer_cast<AnonymousRange> (std::make_shared<SingleIndex >
( std::shared_ptr<RangeBase>( RB::mThis ) ) ); ( std::dynamic_pointer_cast<AnonymousRange>
( std::shared_ptr<RangeBase>( RB::mThis ) ) ) );
} }
} }

View file

@ -64,10 +64,15 @@ namespace MultiArrayTools
class RangeInterface; class RangeInterface;
// index_base.h // index_base.h
class IndexBase; class VirtualIndexWrapperBase;
typedef VirtualIndexWrapperBase VIWB;
// index_base.h // index_base.h
template <typename MetaType> template <class I>
class IndexWrapper;
// index_base.h
template <class I, typename MetaType>
class IndexInterface; class IndexInterface;
// single_range.h // single_range.h

View file

@ -17,64 +17,144 @@ namespace MultiArrayTools
{ {
template <class... Indices> template <class... Indices>
class ContainerIndex : public IndexInterface<std::tuple<typename Indices::MetaType...> > class ContainerIndex : public IndexInterface<ContainerIndex<Indices...>,
std::tuple<typename Indices::MetaType...> >
{ {
public: public:
typedef IndexBase IB; typedef IndexInterface<ContainerIndex<Indices...>,
std::tuple<typename Indices::MetaType...> > IB;
typedef std::tuple<typename Indices::MetaType...> MetaType; typedef std::tuple<typename Indices::MetaType...> MetaType;
typedef std::tuple<std::shared_ptr<Indices>...> IndexPack; typedef std::tuple<std::shared_ptr<Indices>...> IndexPack;
typedef IndexInterface<std::tuple<typename Indices::MetaType...> > IndexI;
typedef ContainerRange<typename Indices::RangeType...> RangeType; typedef ContainerRange<typename Indices::RangeType...> RangeType;
protected: private:
friend IB;
bool mExternControl = false; bool mExternControl = false;
IndexPack mIPack; IndexPack mIPack;
std::array<size_t,sizeof...(Indices)+1> mBlockSizes; std::array<size_t,sizeof...(Indices)+1> mBlockSizes;
public: public:
ContainerIndex() = delete; ContainerIndex() = delete;
template <class MRange>
ContainerIndex(const std::shared_ptr<MRange>& range);
template <size_t N>
auto get() const -> decltype( *std::get<N>( mIPack ) )&;
ContainerIndex& sync(); // recalculate 'IB::mPos' when externalControl == true
ContainerIndex& operator()(const std::shared_ptr<Indices>&... inds); // control via external indices
ContainerIndex& operator()(); // -> sync; just to shorten the code
private:
//ContainerIndex(const ContainerIndex& in); //ContainerIndex(const ContainerIndex& in);
//ContainerIndex& operator=(const ContainerIndex& in); //ContainerIndex& operator=(const ContainerIndex& in);
template <class MRange> // ==== >>>>> STATIC POLYMORPHISM <<<<< ====
ContainerIndex(const std::shared_ptr<MRange>& range);
virtual IndexType type() const override;
virtual ContainerIndex& operator++() override; static IndexType S_type(ContainerIndex* i) { return IndexType::CONT; }
virtual ContainerIndex& operator--() override;
virtual ContainerIndex& operator=(size_t pos) override;
virtual int pp(std::shared_ptr<IndexBase>& idxPtr) override;
virtual int mm(std::shared_ptr<IndexBase>& idxPtr) override;
virtual MetaType meta() const override; static ContainerIndex& S_pp_op(ContainerIndex* i)
virtual ContainerIndex& at(const MetaType& metaPos) override; {
if(i->mExternControl){
virtual bool first() const override; i->mPos = PackNum<sizeof...(Indices)-1>::makePos(i->mIPack);
virtual bool last() const override; }
PackNum<sizeof...(Indices)-1>::pp( i->mIPack );
++i->mPos;
return *i;
}
virtual size_t dim() const override; static ContainerIndex& S_mm_op(ContainerIndex* i)
{
if(i->mExternControl){
i->mPos = PackNum<sizeof...(Indices)-1>::makePos(i->mIPack);
}
PackNum<sizeof...(Indices)-1>::mm( i->mIPack );
--i->mPos;
return *i;
ContainerIndex& sync(); // recalculate 'IB::mPos' when externalControl == true }
static ContainerIndex& S_ass_op(ContainerIndex* i, size_t pos)
{
i->mPos = pos;
PackNum<sizeof...(Indices)-1>::setIndexPack(i->mIPack, pos);
return *i;
}
static int S_pp(ContainerIndex* i, intptr_t idxPtrNum)
{
int tmp = PackNum<sizeof...(Indices)-1>::pp(i->mIPack, i->mBlockSizes, idxPtrNum);
i->mPos += tmp;
return tmp;
}
static int S_mm(ContainerIndex* i, intptr_t idxPtrNum)
{
int tmp = PackNum<sizeof...(Indices)-1>::mm(i->mIPack, i->mBlockSizes, idxPtrNum);
i->mPos -= tmp;
return tmp;
}
static MetaType S_meta(ContainerIndex* i)
{
MetaType metaTuple;
PackNum<sizeof...(Indices)-1>::getMetaPos(metaTuple, i->mIPack);
return metaTuple;
}
static ContainerIndex& S_at(ContainerIndex* i, const MetaType& metaPos)
{
PackNum<sizeof...(Indices)-1>::setMeta(i->mIPack, metaPos);
i->mPos = PackNum<sizeof...(Indices)-1>::makePos(i->mIPack);
return *i;
}
static size_t S_dim(ContainerIndex* i)
{
return sizeof...(Indices);
}
static bool S_first(ContainerIndex* i)
{
return i->pos() == 0;
}
static bool S_last(ContainerIndex* i)
{
return i->pos() == i->mMax - 1;
}
template <size_t N> template <size_t N>
auto get() const -> decltype( *std::get<N>( mIPack ) )&; static auto S_getPtr(ContainerIndex* i) -> decltype( std::get<N>( mIPack ) )&
{
return std::get<N>( i->mIPack );
}
template <size_t N> static std::shared_ptr<VIWB> S_getVPtr(ContainerIndex* i, size_t n)
auto getPtr() const -> decltype( std::get<N>( mIPack ) )&; {
if(n >= sizeof...(Indices)){
assert(0);
// throw !!
}
ContainerIndex<Indices...> const* t = i;
return PackNum<sizeof...(Indices)-1>::getIndexPtr(*t, n);
}
virtual std::shared_ptr<IndexBase> getPtr(size_t n) const override; static size_t S_getStepSize(ContainerIndex* i, size_t n)
virtual size_t getStepSize(size_t n) const override; {
if(n >= sizeof...(Indices)){
assert(0);
// throw !!
}
return i->mBlockSizes[n+1];
}
ContainerIndex& operator()(const std::shared_ptr<Indices>&... inds); // control via external indices static std::string S_id(ContainerIndex* i) { return std::string("con") + std::to_string(IB::mId); }
ContainerIndex& operator()(); // -> sync; just to shorten the code
std::shared_ptr<RangeType> range() const;
virtual std::string id() const override { return std::string("con") + std::to_string(IB::mId); }
}; };
@ -131,7 +211,7 @@ namespace MultiArrayTools
virtual IndexType begin() const override; virtual IndexType begin() const override;
virtual IndexType end() const override; virtual IndexType end() const override;
virtual std::shared_ptr<IndexBase> index() const override; virtual std::shared_ptr<VIWB> index() const override;
friend ContainerRangeFactory<Ranges...>; friend ContainerRangeFactory<Ranges...>;
@ -157,7 +237,7 @@ namespace MultiArrayTools
template <class... Indices> template <class... Indices>
template <class MRange> template <class MRange>
ContainerIndex<Indices...>::ContainerIndex(const std::shared_ptr<MRange>& range) : ContainerIndex<Indices...>::ContainerIndex(const std::shared_ptr<MRange>& range) :
IndexInterface<std::tuple<typename Indices::MetaType...> >(range, 0) IndexInterface<ContainerIndex<Indices...>,std::tuple<typename Indices::MetaType...> >(range, 0)
{ {
PackNum<sizeof...(Indices)-1>::construct(mIPack, *range); PackNum<sizeof...(Indices)-1>::construct(mIPack, *range);
IB::mPos = PackNum<sizeof...(Indices)-1>::makePos(mIPack); IB::mPos = PackNum<sizeof...(Indices)-1>::makePos(mIPack);
@ -165,81 +245,6 @@ namespace MultiArrayTools
PackNum<sizeof...(Indices)-1>::initBlockSizes(mBlockSizes, mIPack); PackNum<sizeof...(Indices)-1>::initBlockSizes(mBlockSizes, mIPack);
} }
template <class... Indices>
IndexType ContainerIndex<Indices...>::type() const
{
return IndexType::CONT;
}
template <class... Indices>
ContainerIndex<Indices...>& ContainerIndex<Indices...>::operator++()
{
if(mExternControl){
IB::mPos = PackNum<sizeof...(Indices)-1>::makePos(mIPack);
}
PackNum<sizeof...(Indices)-1>::pp( mIPack );
++IB::mPos;
return *this;
}
template <class... Indices>
ContainerIndex<Indices...>& ContainerIndex<Indices...>::operator--()
{
if(mExternControl){
IB::mPos = PackNum<sizeof...(Indices)-1>::makePos(mIPack);
}
PackNum<sizeof...(Indices)-1>::mm( mIPack );
--IB::mPos;
return *this;
}
template <class... Indices>
ContainerIndex<Indices...>& ContainerIndex<Indices...>::operator=(size_t pos)
{
IB::mPos = pos;
PackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, pos);
return *this;
}
template <class... Indices>
int ContainerIndex<Indices...>::pp(std::shared_ptr<IndexBase>& idxPtr)
{
int tmp = PackNum<sizeof...(Indices)-1>::pp(mIPack, mBlockSizes, idxPtr);
IB::mPos += tmp;
return tmp;
}
template <class... Indices>
int ContainerIndex<Indices...>::mm(std::shared_ptr<IndexBase>& idxPtr)
{
int tmp = PackNum<sizeof...(Indices)-1>::mm(mIPack, mBlockSizes, idxPtr);
IB::mPos -= tmp;
return tmp;
}
template <class... Indices>
typename ContainerIndex<Indices...>::MetaType ContainerIndex<Indices...>::meta() const
{
MetaType metaTuple;
PackNum<sizeof...(Indices)-1>::getMetaPos(metaTuple, mIPack);
return metaTuple;
}
template <class... Indices>
ContainerIndex<Indices...>& ContainerIndex<Indices...>::at(const MetaType& metaPos)
{
PackNum<sizeof...(Indices)-1>::setMeta(mIPack, metaPos);
IB::mPos = PackNum<sizeof...(Indices)-1>::makePos(mIPack);
return *this;
}
template <class... Indices>
size_t ContainerIndex<Indices...>::dim() const
{
return sizeof...(Indices);
}
template <class... Indices> template <class... Indices>
ContainerIndex<Indices...>& ContainerIndex<Indices...>::sync() ContainerIndex<Indices...>& ContainerIndex<Indices...>::sync()
{ {
@ -259,47 +264,6 @@ namespace MultiArrayTools
return *std::get<N>( mIPack ); return *std::get<N>( mIPack );
} }
template <class... Indices>
template <size_t N>
auto ContainerIndex<Indices...>::getPtr() const -> decltype( std::get<N>( mIPack ) )&
{
return std::get<N>( mIPack );
}
template <class... Indices>
std::shared_ptr<IndexBase> ContainerIndex<Indices...>::getPtr(size_t n) const
{
if(n >= sizeof...(Indices)){
assert(0);
// throw !!
}
ContainerIndex<Indices...> const* t = this;
return PackNum<sizeof...(Indices)-1>::getIndexPtr(*t, n);
}
template <class... Indices>
size_t ContainerIndex<Indices...>::getStepSize(size_t n) const
{
if(n >= sizeof...(Indices)){
assert(0);
// throw !!
}
return mBlockSizes[n+1];
}
template <class... Indices>
bool ContainerIndex<Indices...>::first() const
{
return IB::pos() == 0;
}
template <class... Indices>
bool ContainerIndex<Indices...>::last() const
{
return IB::pos() == IB::mRangePtr->size() - 1;
}
template <class... Indices> template <class... Indices>
ContainerIndex<Indices...>& ContainerIndex<Indices...>::operator()(const std::shared_ptr<Indices>&... inds) ContainerIndex<Indices...>& ContainerIndex<Indices...>::operator()(const std::shared_ptr<Indices>&... inds)
{ {
@ -314,12 +278,6 @@ namespace MultiArrayTools
return sync(); return sync();
} }
template <class... Indices>
std::shared_ptr<typename ContainerIndex<Indices...>::RangeType> ContainerIndex<Indices...>::range() const
{
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr );
}
/***************************** /*****************************
* ContainerRangeFactory * * ContainerRangeFactory *
*****************************/ *****************************/
@ -408,11 +366,12 @@ namespace MultiArrayTools
} }
template <class... Ranges> template <class... Ranges>
std::shared_ptr<IndexBase> ContainerRange<Ranges...>::index() const std::shared_ptr<VIWB> ContainerRange<Ranges...>::index() const
{ {
return std::make_shared<ContainerIndex<typename Ranges::IndexType...> > return std::make_shared<VIWB>
( std::dynamic_pointer_cast<ContainerRange<Ranges...> > ( std::make_shared<ContainerIndex<typename Ranges::IndexType...> >
( std::shared_ptr<RangeBase>( RB::mThis ) ) ); ( std::dynamic_pointer_cast<ContainerRange<Ranges...> >
( std::shared_ptr<RangeBase>( RB::mThis ) ) ) );
} }
} // end namespace MultiArrayTools } // end namespace MultiArrayTools

View file

@ -35,12 +35,11 @@ namespace MultiArrayTools
virtual size_t pos() const = 0; virtual size_t pos() const = 0;
virtual size_t max() const = 0; virtual size_t max() const = 0;
virtual std::shared_ptr<RangeBase> rangePtr() const = 0; virtual std::shared_ptr<RangeBase> rangePtr() const = 0;
virtual VirtualIndexWrapperBase getPtr(size_t n) const = 0; virtual std::shared_ptr<VirtualIndexWrapperBase> getPtr(size_t n) const = 0;
virtual intptr_t getPtrNum() const = 0; virtual intptr_t getPtrNum() const = 0;
virtual size_t getStepSize(size_t n) const = 0;
}; };
typedef VirtualIndexWrapperBase VIWB;
template <class I> template <class I>
std::shared_ptr<IndexWrapper<I> > make_viwb(std::shared_ptr<I> idxPtr) std::shared_ptr<IndexWrapper<I> > make_viwb(std::shared_ptr<I> idxPtr)
{ {
@ -68,7 +67,8 @@ namespace MultiArrayTools
virtual size_t max() const override { return mIdxPtr->max(); } virtual size_t max() const override { return mIdxPtr->max(); }
virtual std::shared_ptr<RangeBase> rangePtr() const override { return mIdxPtr->rangePtr(); } virtual std::shared_ptr<RangeBase> rangePtr() const override { return mIdxPtr->rangePtr(); }
virtual std::shared_ptr<VirtualIndexWrapperBase> getPtr(size_t n) const override { return mIdxPtr->getv(n); } virtual std::shared_ptr<VirtualIndexWrapperBase> getPtr(size_t n) const override { return mIdxPtr->getv(n); }
virtual intptr_t getPtrNum() const override { return static_cast<intptr_t>( mIdxPtr.get() ); }; virtual intptr_t getPtrNum() const override { return static_cast<intptr_t>( mIdxPtr.get() ); }
virtual size_t getStepSize(size_t n) const override { return mIdxPtr->getStepSize(n); }
private: private:
std::shared_ptr<I> mIdxPtr; std::shared_ptr<I> mIdxPtr;
@ -78,9 +78,12 @@ namespace MultiArrayTools
class IndexInterface class IndexInterface
{ {
public: public:
typedef typename I::RangeType RangeType;
//DEFAULT_MEMBERS(IndexInterface); //DEFAULT_MEMBERS(IndexInterface);
I* THIS() { return static_cast<I*>(this); } I* THIS() { return static_cast<I*>(this); }
I const* THIS() const { return static_cast<I const*>(this); }
~IndexInterface() = default; ~IndexInterface() = default;
@ -103,7 +106,8 @@ namespace MultiArrayTools
bool last() const { return I::S_last(THIS()); } bool last() const { return I::S_last(THIS()); }
bool first() const { return I::S_first(THIS()); } bool first() const { return I::S_first(THIS()); }
std::shared_ptr<RangeBase> rangePtr() const; std::shared_ptr<RangeBase> vrange() const { return mRangePtr; }
std::shared_ptr<RangeType> range() const { return std::dynamic_pointer_cast<RangeType>(mRangePtr); }
template <size_t N> template <size_t N>
auto getPtr() const -> decltype(I::S_get<N>(THIS())) { return I::S_get<N>(THIS()); } auto getPtr() const -> decltype(I::S_get<N>(THIS())) { return I::S_get<N>(THIS()); }
@ -118,9 +122,12 @@ namespace MultiArrayTools
MetaType meta() const { return I::S_meta(THIS()); } MetaType meta() const { return I::S_meta(THIS()); }
IndexInterface& at(const MetaType& meta) { return I::S_at(THIS(), meta); } IndexInterface& at(const MetaType& meta) { return I::S_at(THIS(), meta); }
protected:
private:
friend I;
IndexInterface() { mId = indexId(); } IndexInterface() { mId = indexId(); }
IndexInterface(IndexInterface&& in) = default; IndexInterface(IndexInterface&& in) = default;
IndexInterface& operator=(IndexInterface&& in) = default; IndexInterface& operator=(IndexInterface&& in) = default;
@ -130,7 +137,7 @@ namespace MultiArrayTools
std::shared_ptr<RangeBase> mRangePtr; std::shared_ptr<RangeBase> mRangePtr;
size_t mPos; size_t mPos;
size_t mId; size_t mId;
size_t mMax;
}; };
} }
@ -141,14 +148,15 @@ namespace MultiArrayTools
namespace MultiArrayTools namespace MultiArrayTools
{ {
/***************** /**********************
* IndexInterface * * IndexInterface *
*****************/ **********************/
template <class I, typename MetaType> template <class I, typename MetaType>
IndexInterface<I,MetaType>::IndexInterface(const std::shared_ptr<RangeBase>& range, IndexInterface<I,MetaType>::IndexInterface(const std::shared_ptr<RangeBase>& range,
size_t pos) : mRangePtr(range), size_t pos) : mRangePtr(range),
mPos(pos) mPos(pos),
mMax(mRangePtr->size())
{ {
mId = indexId(); mId = indexId();
} }
@ -174,13 +182,7 @@ namespace MultiArrayTools
template <class I, typename MetaType> template <class I, typename MetaType>
size_t IndexInterface<I,MetaType>::max() const size_t IndexInterface<I,MetaType>::max() const
{ {
return mRangePtr->size(); return mMax;
}
template <class I, typename MetaType>
std::shared_ptr<RangeBase> IndexInterface<I,MetaType>::rangePtr() const
{
return mRangePtr;
} }
template <class I, typename MetaType> template <class I, typename MetaType>

View file

@ -56,36 +56,7 @@ namespace MultiArrayTools
template <class OpClass> template <class OpClass>
std::shared_ptr<VIWB> seekBlockIndex(std::shared_ptr<VIWB> ownIdx, std::shared_ptr<VIWB> seekBlockIndex(std::shared_ptr<VIWB> ownIdx,
const OpClass& second); const OpClass& second);
/*
template <typename T>
class OperationBase
{
public:
typedef T value_type;
OperationBase() = default;
virtual ~OperationBase() = default;
// init block, return resulting type (BLOCK, VALUE, SPLIT)
virtual std::vector<BTSS> block(const std::shared_ptr<IndexBase> blockIndex) const = 0;
virtual const OperationBase& block() const = 0; // update block
//virtual size_t argNum() const = 0;
virtual const Block<T>& get() const = 0;
};
template <typename T>
class MutableOperationBase : public OperationBase<T>
{
public:
typedef T value_type;
MutableOperationBase() = default;
virtual MBlock<T>& get() = 0;
};
*/
template <typename T, class OperationClass> template <typename T, class OperationClass>
class OperationTemplate class OperationTemplate
{ {
@ -333,7 +304,7 @@ namespace MultiArrayTools
return out; return out;
} }
void minimizeAppearanceOfType(std::map<std::shared_ptr<IndexBase>, std::vector<BTSS> >& mp, void minimizeAppearanceOfType(std::map<std::shared_ptr<VIWB>, std::vector<BTSS> >& mp,
BlockType bt) BlockType bt)
{ {
size_t minNum = getBTNum( mp.begin()->second, bt ); size_t minNum = getBTNum( mp.begin()->second, bt );
@ -357,12 +328,12 @@ namespace MultiArrayTools
} }
template <class OpClass> template <class OpClass>
std::shared_ptr<IndexBase> seekBlockIndex(std::shared_ptr<IndexBase> ownIdx, std::shared_ptr<VIWB> seekBlockIndex(std::shared_ptr<VIWB> ownIdx,
const OpClass& second) const OpClass& second)
{ {
std::vector<std::shared_ptr<IndexBase> > ivec; std::vector<std::shared_ptr<VIWB> > ivec;
seekIndexInst(ownIdx, ivec); seekIndexInst(ownIdx, ivec);
std::map<std::shared_ptr<IndexBase>, std::vector<BTSS> > mp; std::map<std::shared_ptr<VIWB>, std::vector<BTSS> > mp;
for(auto& xx: ivec){ for(auto& xx: ivec){
mp[xx] = second.block(xx); mp[xx] = second.block(xx);
@ -465,7 +436,7 @@ namespace MultiArrayTools
} }
template <typename T, class OpClass, class... Ranges> template <typename T, class OpClass, class... Ranges>
std::vector<BTSS> OperationMaster<T,OpClass,Ranges...>::block(const std::shared_ptr<IndexBase> blockIndex) const std::vector<BTSS> OperationMaster<T,OpClass,Ranges...>::block(const std::shared_ptr<VIWB> blockIndex) const
{ {
std::vector<BTSS> btv(1, getBlockType(mIndex, blockIndex, true) ); std::vector<BTSS> btv(1, getBlockType(mIndex, blockIndex, true) );
mBlockPtr = makeBlock(mArrayRef.datav(), btv[0].second, blockIndex->max()); mBlockPtr = makeBlock(mArrayRef.datav(), btv[0].second, blockIndex->max());
@ -501,7 +472,7 @@ namespace MultiArrayTools
} }
template <typename T, class... Ranges> template <typename T, class... Ranges>
std::vector<BTSS> ConstOperationRoot<T,Ranges...>::block(const std::shared_ptr<IndexBase> blockIndex) const std::vector<BTSS> ConstOperationRoot<T,Ranges...>::block(const std::shared_ptr<VIWB> blockIndex) const
{ {
std::vector<BTSS> btv(1, getBlockType(mIndex, blockIndex, true) ); std::vector<BTSS> btv(1, getBlockType(mIndex, blockIndex, true) );
mBlockPtr = makeBlock(mArrayRef.datav(), btv[0].second, blockIndex->max()); mBlockPtr = makeBlock(mArrayRef.datav(), btv[0].second, blockIndex->max());
@ -551,7 +522,7 @@ namespace MultiArrayTools
} }
template <typename T, class... Ranges> template <typename T, class... Ranges>
std::vector<BTSS> OperationRoot<T,Ranges...>::block(const std::shared_ptr<IndexBase> blockIndex) const std::vector<BTSS> OperationRoot<T,Ranges...>::block(const std::shared_ptr<VIWB> blockIndex) const
{ {
std::vector<BTSS> btv(1, getBlockType(mIndex, blockIndex, true) ); std::vector<BTSS> btv(1, getBlockType(mIndex, blockIndex, true) );
mBlockPtr = makeBlock(mArrayRef.datav(), btv[0].second, blockIndex->max()); mBlockPtr = makeBlock(mArrayRef.datav(), btv[0].second, blockIndex->max());
@ -582,7 +553,7 @@ namespace MultiArrayTools
} }
template <typename T, class OpFunction, class... Ops> template <typename T, class OpFunction, class... Ops>
std::vector<BTSS> Operation<T,OpFunction,Ops...>::block(const std::shared_ptr<IndexBase> blockIndex) const std::vector<BTSS> Operation<T,OpFunction,Ops...>::block(const std::shared_ptr<VIWB> blockIndex) const
{ {
std::vector<BTSS> btv; std::vector<BTSS> btv;
PackNum<sizeof...(Ops)-1>::makeBlockTypeVec(btv, mOps, blockIndex); PackNum<sizeof...(Ops)-1>::makeBlockTypeVec(btv, mOps, blockIndex);
@ -617,7 +588,7 @@ namespace MultiArrayTools
} }
template <typename T, class Op, class IndexType> template <typename T, class Op, class IndexType>
std::vector<BTSS> Contraction<T,Op,IndexType>::block(const std::shared_ptr<IndexBase> blockIndex) const std::vector<BTSS> Contraction<T,Op,IndexType>::block(const std::shared_ptr<VIWB> blockIndex) const
{ {
return mOp.block(blockIndex); return mOp.block(blockIndex);
} }

View file

@ -15,24 +15,32 @@
namespace MultiArrayTools namespace MultiArrayTools
{ {
namespace
{
using namespace MultiArrayHelper;
}
template <class... Indices> template <class... Indices>
class MultiIndex : public IndexInterface<std::tuple<typename Indices::MetaType...> > class MultiIndex : public IndexInterface<MultiIndex<Indices...>,
std::tuple<typename Indices::MetaType...> >
{ {
public: public:
typedef IndexBase IB; typedef IndexInterface<MultiIndex<Indices...>,
std::tuple<typename Indices::MetaType...> > IB;
typedef std::tuple<std::shared_ptr<Indices>...> IndexPack; typedef std::tuple<std::shared_ptr<Indices>...> IndexPack;
typedef std::tuple<typename Indices::MetaType...> MetaType; typedef std::tuple<typename Indices::MetaType...> MetaType;
typedef IndexInterface<MetaType> IndexI;
typedef MultiRange<typename Indices::RangeType...> RangeType; typedef MultiRange<typename Indices::RangeType...> RangeType;
protected: private:
IndexPack mIPack; IndexPack mIPack;
std::array<size_t,sizeof...(Indices)+1> mBlockSizes; std::array<size_t,sizeof...(Indices)+1> mBlockSizes;
public: public:
MultiIndex() = delete; MultiIndex() = delete;
// NO DEFAULT HERE !!! // NO DEFAULT HERE !!!
// ( have to assign sub-indices (ptr!) correctly ) // ( have to assign sub-indices (ptr!) correctly )
//MultiIndex(const MultiIndex& in); //MultiIndex(const MultiIndex& in);
@ -42,50 +50,119 @@ namespace MultiArrayTools
template <class MRange> template <class MRange>
MultiIndex(const std::shared_ptr<MRange>& range); MultiIndex(const std::shared_ptr<MRange>& range);
virtual IndexType type() const override;
virtual MultiIndex& operator++() override;
virtual MultiIndex& operator--() override;
virtual MultiIndex& operator=(size_t pos) override;
virtual int pp(std::shared_ptr<IndexBase>& idxPtr) override;
virtual int mm(std::shared_ptr<IndexBase>& idxPtr) override;
template <size_t DIR> template <size_t DIR>
MultiIndex& up(); MultiIndex& up();
template <size_t DIR> template <size_t DIR>
MultiIndex& down(); MultiIndex& down();
template <size_t N> template <size_t N>
auto get() const -> decltype( *std::get<N>( mIPack ) )&; auto get() const -> decltype( *std::get<N>( mIPack ) )&;
template <size_t N>
auto getPtr() const -> decltype( std::get<N>( mIPack ) )&;
const IndexBase& get(size_t n) const;
virtual std::shared_ptr<IndexBase> getPtr(size_t n) const override;
virtual size_t getStepSize(size_t n) const override;
virtual MetaType meta() const override;
virtual MultiIndex& at(const MetaType& metaPos) override;
virtual bool first() const override;
virtual bool last() const override;
virtual size_t dim() const override;
std::shared_ptr<RangeType> range() const;
//virtual MultiIndex& lock(std::shared_ptr<IndexBase>& idx) override;
// raplace instances (in contrast to its analogon in ContainerIndex // raplace instances (in contrast to its analogon in ContainerIndex
// MultiIndices CANNOT be influences be its subindices, so there is // MultiIndices CANNOT be influences be its subindices, so there is
// NO foreign/external controll) // NO foreign/external controll)
// Do NOT share index instances between two or more MultiIndex instances // Do NOT share index instances between two or more MultiIndex instances
MultiIndex& operator()(std::shared_ptr<Indices>&... indices); MultiIndex& operator()(std::shared_ptr<Indices>&... indices);
virtual std::string id() const override { return std::string("mul") + std::to_string(IB::mId); } private:
friend IB;
// ==== >>>>> STATIC POLYMORPHISM <<<<< ====
static IndexType S_type(MultiIndex* i) { return IndexType::MULTI; }
static MultiIndex& S_ass_op(MultiIndex* i, size_t pos)
{
i->mPos = pos;
PackNum<sizeof...(Indices)-1>::setIndexPack(i->mIPack, pos);
return *i;
}
static MultiIndex& S_pp_op(MultiIndex* i)
{
PackNum<sizeof...(Indices)-1>::pp( i->mIPack );
++i->mPos;
return *i;
}
static MultiIndex& S_mm_op(MultiIndex* i)
{
PackNum<sizeof...(Indices)-1>::mm( i->mIPack );
--i->mPos;
return *i;
}
static int S_pp(MultiIndex* i, intptr_t idxPtrNum)
{
int tmp = PackNum<sizeof...(Indices)-1>::pp(i->mIPack, i->mBlockSizes, idxPtrNum);
i->mPos += tmp;
return tmp;
}
static int S_mm(MultiIndex* i, intptr_t idxPtrNum)
{
int tmp = PackNum<sizeof...(Indices)-1>::mm(i->mIPack, i->mBlockSizes, idxPtrNum);
i->mPos -= tmp;
return tmp;
}
static MetaType S_meta(MultiIndex* i)
{
MetaType metaTuple;
PackNum<sizeof...(Indices)-1>::getMetaPos(metaTuple, i->mIPack);
return metaTuple;
}
static MultiIndex& S_at(MultiIndex* i, const MetaType& metaPos)
{
PackNum<sizeof...(Indices)-1>::setMeta(i->mIPack, metaPos);
i->mPos = PackNum<sizeof...(Indices)-1>::makePos(i->mIPack);
return *i;
}
static size_t S_dim(MultiIndex* i)
{
return sizeof...(Indices);
}
static bool S_first(MultiIndex* i)
{
return i->mPos == 0;
}
static bool S_last(MultiIndex* i)
{
return i->mPos == i->mMax - 1;
}
template <size_t N>
static auto S_getPtr(MultiIndex* i) -> decltype( std::get<N>( mIPack ) )&
{
return std::get<N>(i->mIPack);
}
//const IndexBase& get(size_t n);
static std::shared_ptr<VIWB> S_getVPtr(MultiIndex* i, size_t n)
{
if(n >= sizeof...(Indices)){
assert(0);
// throw !!
}
MultiIndex<Indices...> const* t = i;
return PackNum<sizeof...(Indices)-1>::getIndexPtr(*t, n);
}
static size_t S_getStepSize(MultiIndex* i, size_t n)
{
if(n >= sizeof...(Indices)){
assert(0);
// throw !!
}
return i->mBlockSizes[n+1];
}
static std::string S_id(MultiIndex* i) { return std::string("mul") + std::to_string(IB::mId); }
}; };
/************************* /*************************
@ -146,7 +223,7 @@ namespace MultiArrayTools
virtual IndexType begin() const override; virtual IndexType begin() const override;
virtual IndexType end() const override; virtual IndexType end() const override;
virtual std::shared_ptr<IndexBase> index() const override; virtual std::shared_ptr<VIWB> index() const override;
friend MultiRangeFactory<Ranges...>; friend MultiRangeFactory<Ranges...>;
@ -199,7 +276,7 @@ namespace MultiArrayTools
template <class... Indices> template <class... Indices>
template <class MRange> template <class MRange>
MultiIndex<Indices...>::MultiIndex(const std::shared_ptr<MRange>& range) : MultiIndex<Indices...>::MultiIndex(const std::shared_ptr<MRange>& range) :
IndexInterface<std::tuple<typename Indices::MetaType...> >(range, 0) IndexInterface<MultiIndex<Indices...>,std::tuple<typename Indices::MetaType...> >(range, 0)
{ {
PackNum<sizeof...(Indices)-1>::construct(mIPack, *range); PackNum<sizeof...(Indices)-1>::construct(mIPack, *range);
IB::mPos = PackNum<sizeof...(Indices)-1>::makePos(mIPack); IB::mPos = PackNum<sizeof...(Indices)-1>::makePos(mIPack);
@ -207,52 +284,6 @@ namespace MultiArrayTools
PackNum<sizeof...(Indices)-1>::initBlockSizes(mBlockSizes, mIPack); // has one more element! PackNum<sizeof...(Indices)-1>::initBlockSizes(mBlockSizes, mIPack); // has one more element!
} }
template <class... Indices>
IndexType MultiIndex<Indices...>::type() const
{
return IndexType::MULTI;
}
template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator++()
{
PackNum<sizeof...(Indices)-1>::pp( mIPack );
++IB::mPos;
return *this;
}
template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator--()
{
PackNum<sizeof...(Indices)-1>::mm( mIPack );
--IB::mPos;
return *this;
}
template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator=(size_t pos)
{
IB::mPos = pos;
PackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, pos);
return *this;
}
template <class... Indices>
int MultiIndex<Indices...>::pp(std::shared_ptr<IndexBase>& idxPtr)
{
int tmp = PackNum<sizeof...(Indices)-1>::pp(mIPack, mBlockSizes, idxPtr);
IB::mPos += tmp;
return tmp;
}
template <class... Indices>
int MultiIndex<Indices...>::mm(std::shared_ptr<IndexBase>& idxPtr)
{
int tmp = PackNum<sizeof...(Indices)-1>::mm(mIPack, mBlockSizes, idxPtr);
IB::mPos -= tmp;
return tmp;
}
template <class... Indices> template <class... Indices>
template <size_t DIR> template <size_t DIR>
MultiIndex<Indices...>& MultiIndex<Indices...>::up() MultiIndex<Indices...>& MultiIndex<Indices...>::up()
@ -273,12 +304,6 @@ namespace MultiArrayTools
return *this; return *this;
} }
template <class... Indices>
size_t MultiIndex<Indices...>::dim() const
{
return sizeof...(Indices);
}
template <class... Indices> template <class... Indices>
template <size_t N> template <size_t N>
auto MultiIndex<Indices...>::get() const -> decltype( *std::get<N>( mIPack ) )& auto MultiIndex<Indices...>::get() const -> decltype( *std::get<N>( mIPack ) )&
@ -286,87 +311,6 @@ namespace MultiArrayTools
return *std::get<N>(mIPack); return *std::get<N>(mIPack);
} }
template <class... Indices>
template <size_t N>
auto MultiIndex<Indices...>::getPtr() const -> decltype( std::get<N>( mIPack ) )&
{
return std::get<N>(mIPack);
}
template <class... Indices>
const IndexBase& MultiIndex<Indices...>::get(size_t n) const
{
if(n >= sizeof...(Indices)){
assert(0);
// throw !!
}
MultiIndex<Indices...> const* t = this;
return PackNum<sizeof...(Indices)-1>::getIndex(*t, n);
}
template <class... Indices>
std::shared_ptr<IndexBase> MultiIndex<Indices...>::getPtr(size_t n) const
{
if(n >= sizeof...(Indices)){
assert(0);
// throw !!
}
MultiIndex<Indices...> const* t = this;
return PackNum<sizeof...(Indices)-1>::getIndexPtr(*t, n);
}
template <class... Indices>
size_t MultiIndex<Indices...>::getStepSize(size_t n) const
{
if(n >= sizeof...(Indices)){
assert(0);
// throw !!
}
return mBlockSizes[n+1];
}
template <class... Indices>
typename MultiIndex<Indices...>::MetaType MultiIndex<Indices...>::meta() const
{
MetaType metaTuple;
PackNum<sizeof...(Indices)-1>::getMetaPos(metaTuple, mIPack);
return metaTuple;
}
template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::at(const MultiIndex<Indices...>::MetaType& metaPos)
{
PackNum<sizeof...(Indices)-1>::setMeta(mIPack, metaPos);
IB::mPos = PackNum<sizeof...(Indices)-1>::makePos(mIPack);
return *this;
}
template <class... Indices>
bool MultiIndex<Indices...>::first() const
{
return IB::mPos == 0;
}
template <class... Indices>
bool MultiIndex<Indices...>::last() const
{
return IB::mPos == IB::mRangePtr->size() - 1;
}
template <class... Indices>
std::shared_ptr<typename MultiIndex<Indices...>::RangeType> MultiIndex<Indices...>::range() const
{
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr );
}
/*
template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::lock(std::shared_ptr<IndexBase>& idx)
{
IB::mLocked = (idx.get() == this);
PackNum<sizeof...(Indices)-1>::lock(mIPack, idx);
return *this;
}*/
template <class... Indices> template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator()(std::shared_ptr<Indices>&... indices) MultiIndex<Indices...>& MultiIndex<Indices...>::operator()(std::shared_ptr<Indices>&... indices)
{ {
@ -467,11 +411,12 @@ namespace MultiArrayTools
} }
template <class... Ranges> template <class... Ranges>
std::shared_ptr<IndexBase> MultiRange<Ranges...>::index() const std::shared_ptr<VIWB> MultiRange<Ranges...>::index() const
{ {
return std::make_shared<MultiIndex<typename Ranges::IndexType...> > return std::make_shared<VIWB>
( std::dynamic_pointer_cast<MultiRange<Ranges...> > ( std::make_shared<MultiIndex<typename Ranges::IndexType...> >
( std::shared_ptr<RangeBase>( RB::mThis ) ) ); ( std::dynamic_pointer_cast<MultiRange<Ranges...> >
( std::shared_ptr<RangeBase>( RB::mThis ) ) ) );
} }
} }

View file

@ -90,10 +90,10 @@ namespace MultiArrayHelper
auto& siPtr = std::get<N>(ip); auto& siPtr = std::get<N>(ip);
//VCHECK(siPtr.id()); //VCHECK(siPtr.id());
if(static_cast<intptr_t>(siPtr.get()) == idxPtrNum){ if(static_cast<intptr_t>(siPtr.get()) == idxPtrNum){
return PackNum<N-1>::pp(ip, bs, idxPtrNum; return PackNum<N-1>::pp(ip, bs, idxPtrNum);
} }
else { else {
int tmp = siPtr->pp(idxPtr); int tmp = siPtr->pp(idxPtrNum);
if(siPtr->pos() == siPtr->max()){ if(siPtr->pos() == siPtr->max()){
(*siPtr) = 0; (*siPtr) = 0;
return PackNum<N-1>::pp(ip, bs, idxPtrNum) - siPtr->max() + 1; return PackNum<N-1>::pp(ip, bs, idxPtrNum) - siPtr->max() + 1;
@ -233,7 +233,7 @@ namespace MultiArrayHelper
template <class... Ops> template <class... Ops>
static void makeBlockTypeVec(std::vector<std::pair<BlockType,size_t> >& btv, static void makeBlockTypeVec(std::vector<std::pair<BlockType,size_t> >& btv,
const std::tuple<Ops...>& ops, const std::tuple<Ops...>& ops,
std::shared_ptr<IndexBase> idxPtr) std::shared_ptr<VIWB> idxPtr)
{ {
auto subvec = std::move( std::get<N>(ops).block(idxPtr) ); auto subvec = std::move( std::get<N>(ops).block(idxPtr) );
btv.insert(btv.end(), subvec.begin(), subvec.end() ); btv.insert(btv.end(), subvec.begin(), subvec.end() );
@ -271,7 +271,7 @@ namespace MultiArrayHelper
} }
*/ */
template <class IndexType> template <class IndexType>
static std::shared_ptr<IndexBase> getIndexPtr(const IndexType& in, size_t n) static std::shared_ptr<VIWB> getIndexPtr(const IndexType& in, size_t n)
{ {
return make_viwb( in.template get<0>() ); return make_viwb( in.template get<0>() );
} }
@ -423,7 +423,7 @@ namespace MultiArrayHelper
template <class... Ops> template <class... Ops>
static void makeBlockTypeVec(std::vector<std::pair<BlockType,size_t> >& btv, static void makeBlockTypeVec(std::vector<std::pair<BlockType,size_t> >& btv,
const std::tuple<Ops...>& ops, const std::tuple<Ops...>& ops,
std::shared_ptr<IndexBase> idxPtr) std::shared_ptr<VIWB> idxPtr)
{ {
auto subvec = std::move( std::get<0>(ops).block(idxPtr) ); auto subvec = std::move( std::get<0>(ops).block(idxPtr) );
btv.insert(btv.end(), subvec.begin(), subvec.end() ); btv.insert(btv.end(), subvec.begin(), subvec.end() );

View file

@ -19,7 +19,7 @@ namespace MultiArrayTools
{ {
public: public:
typedef IndexBase<SingleIndex<U,TYPE>,U> IB; typedef IndexInterface<SingleIndex<U,TYPE>,U> IB;
typedef U MetaType; typedef U MetaType;
typedef SingleRange<U,TYPE> RangeType; typedef SingleRange<U,TYPE> RangeType;
@ -27,30 +27,87 @@ namespace MultiArrayTools
SingleIndex(const std::shared_ptr<SingleRange<U,TYPE> >& range); SingleIndex(const std::shared_ptr<SingleRange<U,TYPE> >& range);
static IndexType S_type(SingleIndex* i) const; private:
static SingleIndex& S_ass_op(SingleIndex* i, size_t pos);
static SingleIndex& S_pp_op(SingleIndex* i);
static SingleIndex& S_mm_op(SingleIndex* i);
static int S_pp(SingleIndex* i, std::shared_ptr<VIWB>& idxPtr); friend IB;
static int S_mm(SingleIndex* i, std::shared_ptr<VIWB>& idxPtr);
// ==== >>>>> STATIC POLYMORPHISM <<<<< ====
static U S_meta(SingleIndex* i) const; static IndexType S_type(SingleIndex* i)
static SingleIndex& S_at(SingleIndex* i, const U& metaPos); {
return IndexType::SINGLE;
}
static size_t S_dim(SingleIndex* i) const; // = 1 static SingleIndex& S_ass_op(SingleIndex* i, size_t pos)
static bool S_last(SingleIndex* i) const; {
static bool S_first(SingleIndex* i) const; i->mPos = pos;
return *i;
}
static SingleIndex& S_pp_op(SingleIndex* i)
{
++i->mPos;
return *i;
}
static SingleIndex& S_mm_op(SingleIndex* i)
{
--i->mPos;
return *i;
}
static int S_pp(SingleIndex* i, intptr_t idxPtrNum)
{
++(*i);
return 1;
}
static int S_mm(SingleIndex* i, intptr_t idxPtrNum)
{
--(*i);
return 1;
}
static U S_meta(SingleIndex* i)
{
return std::dynamic_pointer_cast<SingleRange<U,TYPE> const>( i->mRangePtr )->get( i->pos() );
}
static SingleIndex& S_at(SingleIndex* i, const U& metaPos)
{
operator=( std::dynamic_pointer_cast<SingleRange<U,TYPE> const>( i->mRangePtr )->getMeta( metaPos ) );
return *i;
}
static size_t S_dim(SingleIndex* i) // = 1
{
return 1;
}
static bool S_last(SingleIndex* i)
{
return i->mPos == i->mMax - 1;
}
static bool S_first(SingleIndex* i)
{
return i->mPos == 0;
}
template <size_t N> template <size_t N>
static void S_getPtr(SingleIndex* i) const; static void S_getPtr(SingleIndex* i) {}
std::shared_ptr<VIWB> getVPtr(size_t n) const; static std::shared_ptr<VIWB> S_getVPtr(SingleIndex* i, size_t n)
{
return std::shared_ptr<VIWB>();
}
static size_t S_getStepSize(SingleIndex* i, size_t n) const; static size_t S_getStepSize(SingleIndex* i, size_t n)
{
return 1;
}
static std::string S_id(SingleIndex* i) const { return std::string("sin") + std::to_string(IB::mId); } static std::string S_id(SingleIndex* i) { return std::string("sin") + std::to_string(IB::mId); }
}; };
template <typename U, RangeType TYPE> template <typename U, RangeType TYPE>
@ -109,98 +166,7 @@ namespace MultiArrayTools
template <typename U, RangeType TYPE> template <typename U, RangeType TYPE>
SingleIndex<U,TYPE>::SingleIndex(const std::shared_ptr<SingleRange<U,TYPE> >& range) : SingleIndex<U,TYPE>::SingleIndex(const std::shared_ptr<SingleRange<U,TYPE> >& range) :
IndexInterface<U>(range, 0) {} IndexInterface<SingleIndex<U,TYPE>,U>(range, 0) {}
template <typename U, RangeType TYPE>
IndexType SingleIndex<U,TYPE>::S_type() const
{
return IndexType::SINGLE;
}
template <typename U, RangeType TYPE>
SingleIndex<U,TYPE>& SingleIndex<U,TYPE>::S_ass_op(size_t pos)
{
IB::mPos = pos;
return *this;
}
template <typename U, RangeType TYPE>
SingleIndex<U,TYPE>& SingleIndex<U,TYPE>::S_pp_op()
{
++IB::mPos;
return *this;
}
template <typename U, RangeType TYPE>
SingleIndex<U,TYPE>& SingleIndex<U,TYPE>::S_mm_op()
{
--IB::mPos;
return *this;
}
template <typename U, RangeType TYPE>
int SingleIndex<U,TYPE>::S_pp(std::shared_ptr<VIWB>& idxPtr)
{
++(*this);
return 1;
}
template <typename U, RangeType TYPE>
int SingleIndex<U,TYPE>::S_mm(std::shared_ptr<VIWB>& idxPtr)
{
--(*this);
return 1;
}
template <typename U, RangeType TYPE>
U SingleIndex<U,TYPE>::S_meta() const
{
return std::dynamic_pointer_cast<SingleRange<U,TYPE> const>( IB::mRangePtr )->get( IB::pos() );
}
template <typename U, RangeType TYPE>
SingleIndex<U,TYPE>& SingleIndex<U,TYPE>::S_at(const U& metaPos)
{
operator=( std::dynamic_pointer_cast<SingleRange<U,TYPE> const>( IB::mRangePtr )->getMeta( metaPos ) );
return *this;
}
template <typename U, RangeType TYPE>
size_t SingleIndex<U,TYPE>::S_dim() const
{
return 1;
}
template <typename U, RangeType TYPE>
bool SingleIndex<U,TYPE>::S_last() const
{
return IB::mPos == IB::mRangePtr->size() - 1;
}
template <typename U, RangeType TYPE>
bool SingleIndex<U,TYPE>::S_first() const
{
return IB::mPos == 0;
}
template <typename U, RangeType TYPE>
template <size_t N>
void SingleIndex<U,TYPE>::S_getPtr() const
{
return;
}
template <typename U, RangeType TYPE>
std::shared_ptr<VIWB> SingleIndex<U,TYPE>::getVPtr(size_t n) const
{
return std::shared_ptr<VIWB>();
}
template <typename U, RangeType TYPE>
size_t SingleIndex<U,TYPE>::S_getStepSize(size_t n) const
{
return 1;
}
/******************** /********************
* SingleRange * * SingleRange *
@ -282,8 +248,8 @@ namespace MultiArrayTools
{ {
return std::make_shared<VIWB> return std::make_shared<VIWB>
( std::make_shared<SingleIndex<U,TYPE> > ( std::make_shared<SingleIndex<U,TYPE> >
( std::dynamic_pointer_cast<SingleRange<U,TYPE> > ( std::dynamic_pointer_cast<SingleRange<U,TYPE> >
( std::shared_ptr<RangeBase>( RB::mThis ) ) ) ); ( std::shared_ptr<RangeBase>( RB::mThis ) ) ) );
} }
} }