fix dynamic ifor issue (at least it compiles...)
This commit is contained in:
parent
305f45103c
commit
e5792bcf7b
26 changed files with 2841 additions and 2633 deletions
141
src/include/expressions.h
Normal file
141
src/include/expressions.h
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
|
||||||
|
#ifndef __expressions_h__
|
||||||
|
#define __expressions_h__
|
||||||
|
|
||||||
|
#include "ranges/dynamic_range.h"
|
||||||
|
#include "multi_array_base.h"
|
||||||
|
#include "multi_array_operation.h"
|
||||||
|
#include "xfor/xfor.h"
|
||||||
|
|
||||||
|
#define Y() ,
|
||||||
|
|
||||||
|
namespace MultiArrayTools
|
||||||
|
{
|
||||||
|
|
||||||
|
//class Expressions1;
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
using DDMA = MultiArrayBase<double,DynamicRange<EC>>;
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
using DDMMA = MutableMultiArrayBase<double,DynamicRange<EC>>;
|
||||||
|
|
||||||
|
template <class EC, class MA>
|
||||||
|
using oo = decltype(std::declval<MA>()(std::declval<std::shared_ptr<DynamicIndex<EC>>>()));
|
||||||
|
|
||||||
|
template <template <class> class OpF, class... oos>
|
||||||
|
using OO = Operation<double,OpF<double>,oos...>;
|
||||||
|
|
||||||
|
template <class EC, template <class> class OpF, class... MAs>
|
||||||
|
using OX = Operation<double,OpF<double>,oo<EC,MAs>...>;
|
||||||
|
/*
|
||||||
|
template <class EC>
|
||||||
|
class ECInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
EC& THIS() { return static_cast<EC&>(*this); }
|
||||||
|
const EC& THIS() const { return static_cast<EC const&>(*this); }
|
||||||
|
|
||||||
|
template <class Expr>
|
||||||
|
auto ifor(size_t step, Expr ex) const
|
||||||
|
-> decltype(THIS().ifor(step, ex))
|
||||||
|
{
|
||||||
|
return THIS().ifor(step, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Expr>
|
||||||
|
auto iforh(size_t step, Expr ex) const
|
||||||
|
-> decltype(THIS().iforh(step, ex))
|
||||||
|
{
|
||||||
|
return THIS().iforh(step, ex);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
template <class EC, class Index>
|
||||||
|
EC makeec(const std::shared_ptr<Index>& i);
|
||||||
|
|
||||||
|
#define V_IFOR_X(Expr) \
|
||||||
|
virtual ExpressionHolder<Expr> iforx(size_t step, Expr ex) const = 0; \
|
||||||
|
virtual ExpressionHolder<Expr> iforhx(size_t step, Expr ex) const = 0
|
||||||
|
|
||||||
|
template <class Index>
|
||||||
|
class E1;
|
||||||
|
|
||||||
|
class Expressions1 //: public ECInterface<Expressions1<X>>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Expressions1 EX;
|
||||||
|
|
||||||
|
template <class Index>
|
||||||
|
static auto make(const std::shared_ptr<Index>& i)
|
||||||
|
-> decltype(makeec<E1<Index>>(i))
|
||||||
|
{
|
||||||
|
return makeec<E1<Index>>(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
V_IFOR_X(OX<EX Y() plus Y() DDMA<EX> Y() DDMA<EX>>);
|
||||||
|
V_IFOR_X(OX<EX Y() minus Y() DDMA<EX> Y() DDMA<EX>>);
|
||||||
|
V_IFOR_X(OX<EX Y() multiplies Y() DDMA<EX> Y() DDMA<EX>>);
|
||||||
|
V_IFOR_X(OX<EX Y() divides Y() DDMA<EX> Y() DDMA<EX>>);
|
||||||
|
|
||||||
|
public:
|
||||||
|
template <class Expr>
|
||||||
|
auto ifor(size_t step, Expr ex) const
|
||||||
|
-> decltype(iforx(step, ex))
|
||||||
|
{
|
||||||
|
return iforx(step, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Expr>
|
||||||
|
auto iforh(size_t step, Expr ex) const
|
||||||
|
-> decltype(iforhx(step, ex))
|
||||||
|
{
|
||||||
|
return iforhx(step, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define O_IFOR_X(Expr,Ind) \
|
||||||
|
virtual ExpressionHolder<Expr> iforx(size_t step, Expr ex) const override final \
|
||||||
|
{ return ExpressionHolder<Expr>(Ind->ifor(step, ex)); } \
|
||||||
|
virtual ExpressionHolder<Expr> iforhx(size_t step, Expr ex) const override final \
|
||||||
|
{ return ExpressionHolder<Expr>(Ind->iforh(step, ex)); }
|
||||||
|
|
||||||
|
template <class Index>
|
||||||
|
class E1 : public Expressions1
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
typedef Expressions1 EX;
|
||||||
|
|
||||||
|
E1() = default;
|
||||||
|
|
||||||
|
std::shared_ptr<Index> mI;
|
||||||
|
|
||||||
|
O_IFOR_X(OX<EX Y() plus Y() DDMA<EX> Y() DDMA<EX>>, mI);
|
||||||
|
O_IFOR_X(OX<EX Y() minus Y() DDMA<EX> Y() DDMA<EX>>, mI);
|
||||||
|
O_IFOR_X(OX<EX Y() multiplies Y() DDMA<EX> Y() DDMA<EX>>, mI);
|
||||||
|
O_IFOR_X(OX<EX Y() divides Y() DDMA<EX> Y() DDMA<EX>>, mI);
|
||||||
|
|
||||||
|
public:
|
||||||
|
E1(const E1& in) = default;
|
||||||
|
E1(E1&& in) = default;
|
||||||
|
E1& operator=(const E1& in) = default;
|
||||||
|
E1& operator=(E1&& in) = default;
|
||||||
|
|
||||||
|
E1(const std::shared_ptr<Index>& i) : mI(i) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class EC, class Index>
|
||||||
|
EC makeec(const std::shared_ptr<Index>& i)
|
||||||
|
{
|
||||||
|
return EC(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace MultiArrayTools
|
||||||
|
|
||||||
|
#endif
|
124
src/include/functional_multi_array.cc.h
Normal file
124
src/include/functional_multi_array.cc.h
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
|
||||||
|
#include "functional_multi_array.h"
|
||||||
|
|
||||||
|
namespace MultiArrayTools
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/****************************
|
||||||
|
* FunctionalMultiArray *
|
||||||
|
****************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
template <typename T, class Range, class Function>
|
||||||
|
FunctionalMultiArray<T,Range,Function>::FunctionalMultiArray(const Range& range) :
|
||||||
|
MultiArrayBase<T,SRanges...>(range), mFunc() {}
|
||||||
|
*/
|
||||||
|
template <bool FISSTATIC>
|
||||||
|
struct Application
|
||||||
|
{
|
||||||
|
template <typename T, class Function, typename Meta>
|
||||||
|
static inline T apply(const std::shared_ptr<Function>& f, const Meta& m)
|
||||||
|
{
|
||||||
|
return (*f)(m);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Application<true>
|
||||||
|
{
|
||||||
|
template <typename T, class Function, typename Meta>
|
||||||
|
static inline T apply(const std::shared_ptr<Function>& f, const Meta& m)
|
||||||
|
{
|
||||||
|
return Function::apply(m);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, class Function, class... SRanges>
|
||||||
|
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges,
|
||||||
|
const std::shared_ptr<Function>& func) :
|
||||||
|
MultiArrayBase<T,SRanges...>(ranges...), mFunc(func) {}
|
||||||
|
|
||||||
|
template <typename T, class Function, class... SRanges>
|
||||||
|
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges) :
|
||||||
|
MultiArrayBase<T,SRanges...>(ranges...) {}
|
||||||
|
|
||||||
|
template <typename T, class Function, class... SRanges>
|
||||||
|
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const typename CRange::Space& space) :
|
||||||
|
MultiArrayBase<T,SRanges...>(space) {}
|
||||||
|
|
||||||
|
template <typename T, class Function, class... SRanges>
|
||||||
|
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const typename CRange::Space& space,
|
||||||
|
const std::shared_ptr<Function>& func) :
|
||||||
|
MultiArrayBase<T,SRanges...>(space), mFunc(func) {}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T, class Function, class... SRanges>
|
||||||
|
const T& FunctionalMultiArray<T,Function,SRanges...>::operator[](const IndexType& i) const
|
||||||
|
{
|
||||||
|
mVal = Application<Function::FISSTATIC>::template apply<T,Function,typename IndexType::MetaType>(mFunc, i.meta());
|
||||||
|
return mVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Function, class... SRanges>
|
||||||
|
const T& FunctionalMultiArray<T,Function,SRanges...>::at(const typename CRange::IndexType::MetaType& meta) const
|
||||||
|
{
|
||||||
|
mVal = Application<Function::FISSTATIC>::template apply<T,Function,typename IndexType::MetaType>(mFunc,meta);
|
||||||
|
return mVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Function, class... SRanges>
|
||||||
|
const T* FunctionalMultiArray<T,Function,SRanges...>::data() const
|
||||||
|
{
|
||||||
|
return &mVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Function, class... SRanges>
|
||||||
|
bool FunctionalMultiArray<T,Function,SRanges...>::isConst() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Function, class... SRanges>
|
||||||
|
bool FunctionalMultiArray<T,Function,SRanges...>::isSlice() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Function, class... SRanges>
|
||||||
|
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > FunctionalMultiArray<T,Function,SRanges...>::anonymous(bool slice) const
|
||||||
|
{
|
||||||
|
assert(0); // think about it carefully
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Function, class... SRanges>
|
||||||
|
ConstOperationRoot<T,SRanges...> FunctionalMultiArray<T,Function,SRanges...>::
|
||||||
|
operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
||||||
|
{
|
||||||
|
if(not mMaPtr){
|
||||||
|
mMaPtr = std::make_shared<MAType>( MAB::mRange->space() );
|
||||||
|
(*mMaPtr)(inds...) = exec(inds...);
|
||||||
|
}
|
||||||
|
return ConstOperationRoot<T,SRanges...>( *mMaPtr, inds... );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
template <typename T, class Function, class... SRanges>
|
||||||
|
auto FunctionalMultiArray<T,Function,SRanges...>::
|
||||||
|
exec(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
||||||
|
-> decltype( mkOperation( mFunc, ConstOperationRoot<typename SRanges::IndexType::MetaType,SRanges>( mkMAObject( inds ), inds) ... ) )
|
||||||
|
{
|
||||||
|
return mkOperation( mFunc, ConstOperationRoot<typename SRanges::IndexType::MetaType,SRanges>( mkMAObject( inds ), inds ) ... );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <typename T, class Function, class... SRanges>
|
||||||
|
auto FunctionalMultiArray<T,Function,SRanges...>::
|
||||||
|
exec(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
||||||
|
-> decltype( mkOperation( mFunc, mkOpObject(inds) ... ) )
|
||||||
|
{
|
||||||
|
return mkOperation( mFunc, mkOpObject(inds) ... );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace MultiArrayTools
|
|
@ -147,126 +147,5 @@ namespace MultiArrayTools
|
||||||
* --- TEMPLATE CODE --- *
|
* --- TEMPLATE CODE --- *
|
||||||
* ========================= */
|
* ========================= */
|
||||||
|
|
||||||
namespace MultiArrayTools
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/****************************
|
|
||||||
* FunctionalMultiArray *
|
|
||||||
****************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
template <typename T, class Range, class Function>
|
|
||||||
FunctionalMultiArray<T,Range,Function>::FunctionalMultiArray(const Range& range) :
|
|
||||||
MultiArrayBase<T,SRanges...>(range), mFunc() {}
|
|
||||||
*/
|
|
||||||
template <bool FISSTATIC>
|
|
||||||
struct Application
|
|
||||||
{
|
|
||||||
template <typename T, class Function, typename Meta>
|
|
||||||
static inline T apply(const std::shared_ptr<Function>& f, const Meta& m)
|
|
||||||
{
|
|
||||||
return (*f)(m);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct Application<true>
|
|
||||||
{
|
|
||||||
template <typename T, class Function, typename Meta>
|
|
||||||
static inline T apply(const std::shared_ptr<Function>& f, const Meta& m)
|
|
||||||
{
|
|
||||||
return Function::apply(m);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, class Function, class... SRanges>
|
|
||||||
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges,
|
|
||||||
const std::shared_ptr<Function>& func) :
|
|
||||||
MultiArrayBase<T,SRanges...>(ranges...), mFunc(func) {}
|
|
||||||
|
|
||||||
template <typename T, class Function, class... SRanges>
|
|
||||||
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges) :
|
|
||||||
MultiArrayBase<T,SRanges...>(ranges...) {}
|
|
||||||
|
|
||||||
template <typename T, class Function, class... SRanges>
|
|
||||||
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const typename CRange::Space& space) :
|
|
||||||
MultiArrayBase<T,SRanges...>(space) {}
|
|
||||||
|
|
||||||
template <typename T, class Function, class... SRanges>
|
|
||||||
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const typename CRange::Space& space,
|
|
||||||
const std::shared_ptr<Function>& func) :
|
|
||||||
MultiArrayBase<T,SRanges...>(space), mFunc(func) {}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, class Function, class... SRanges>
|
|
||||||
const T& FunctionalMultiArray<T,Function,SRanges...>::operator[](const IndexType& i) const
|
|
||||||
{
|
|
||||||
mVal = Application<Function::FISSTATIC>::template apply<T,Function,typename IndexType::MetaType>(mFunc, i.meta());
|
|
||||||
return mVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Function, class... SRanges>
|
|
||||||
const T& FunctionalMultiArray<T,Function,SRanges...>::at(const typename CRange::IndexType::MetaType& meta) const
|
|
||||||
{
|
|
||||||
mVal = Application<Function::FISSTATIC>::template apply<T,Function,typename IndexType::MetaType>(mFunc,meta);
|
|
||||||
return mVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Function, class... SRanges>
|
|
||||||
const T* FunctionalMultiArray<T,Function,SRanges...>::data() const
|
|
||||||
{
|
|
||||||
return &mVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Function, class... SRanges>
|
|
||||||
bool FunctionalMultiArray<T,Function,SRanges...>::isConst() const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Function, class... SRanges>
|
|
||||||
bool FunctionalMultiArray<T,Function,SRanges...>::isSlice() const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Function, class... SRanges>
|
|
||||||
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > FunctionalMultiArray<T,Function,SRanges...>::anonymous(bool slice) const
|
|
||||||
{
|
|
||||||
assert(0); // think about it carefully
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Function, class... SRanges>
|
|
||||||
ConstOperationRoot<T,SRanges...> FunctionalMultiArray<T,Function,SRanges...>::
|
|
||||||
operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
|
||||||
{
|
|
||||||
if(not mMaPtr){
|
|
||||||
mMaPtr = std::make_shared<MAType>( MAB::mRange->space() );
|
|
||||||
(*mMaPtr)(inds...) = exec(inds...);
|
|
||||||
}
|
|
||||||
return ConstOperationRoot<T,SRanges...>( *mMaPtr, inds... );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
template <typename T, class Function, class... SRanges>
|
|
||||||
auto FunctionalMultiArray<T,Function,SRanges...>::
|
|
||||||
exec(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
|
||||||
-> decltype( mkOperation( mFunc, ConstOperationRoot<typename SRanges::IndexType::MetaType,SRanges>( mkMAObject( inds ), inds) ... ) )
|
|
||||||
{
|
|
||||||
return mkOperation( mFunc, ConstOperationRoot<typename SRanges::IndexType::MetaType,SRanges>( mkMAObject( inds ), inds ) ... );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
template <typename T, class Function, class... SRanges>
|
|
||||||
auto FunctionalMultiArray<T,Function,SRanges...>::
|
|
||||||
exec(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
|
||||||
-> decltype( mkOperation( mFunc, mkOpObject(inds) ... ) )
|
|
||||||
{
|
|
||||||
return mkOperation( mFunc, mkOpObject(inds) ... );
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MultiArrayTools
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
117
src/include/helper_tools.cc.h
Normal file
117
src/include/helper_tools.cc.h
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
|
||||||
|
#include "helper_tools.h"
|
||||||
|
|
||||||
|
namespace MultiArrayTools
|
||||||
|
{
|
||||||
|
template <typename... T>
|
||||||
|
std::ostream& operator<<(std::ostream& out, const std::tuple<T...>& tp)
|
||||||
|
{
|
||||||
|
PackNum<sizeof...(T)-1>::printTuple(out, tp);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class RangeType>
|
||||||
|
auto getIndex(std::shared_ptr<RangeType> range)
|
||||||
|
-> std::shared_ptr<typename RangeType::IndexType>
|
||||||
|
{
|
||||||
|
return std::make_shared<typename RangeType::IndexType>(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class RangeType>
|
||||||
|
auto getIndex()
|
||||||
|
-> std::shared_ptr<typename RangeType::IndexType>
|
||||||
|
{
|
||||||
|
static_assert( RangeType::defaultable,
|
||||||
|
/*typeid(typename RangeType).name() + */" is not defaultable" );
|
||||||
|
static auto f = RangeType::factory();
|
||||||
|
static auto r = std::dynamic_pointer_cast<RangeType>( f.create() );
|
||||||
|
return std::make_shared<typename RangeType::IndexType>(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... RangeTypes>
|
||||||
|
auto mkMulti(std::shared_ptr<RangeTypes>... ranges)
|
||||||
|
-> std::shared_ptr<MultiRange<RangeTypes...> >
|
||||||
|
{
|
||||||
|
MultiRangeFactory<RangeTypes...> mrf( ranges... );
|
||||||
|
return std::dynamic_pointer_cast<MultiRange<RangeTypes...> >( mrf.create() );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... IndexTypes>
|
||||||
|
auto mkMIndex(std::shared_ptr<IndexTypes>... indices)
|
||||||
|
-> decltype( getIndex( mkMulti( indices->range()... ) ) )
|
||||||
|
{
|
||||||
|
auto mi = getIndex( mkMulti( indices->range()... ) );
|
||||||
|
(*mi)( indices... );
|
||||||
|
return mi;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Func, class... RangeTypes>
|
||||||
|
auto mkMapR(const std::shared_ptr<Func>& f, std::shared_ptr<RangeTypes>... ranges)
|
||||||
|
-> std::shared_ptr<MapRange<FunctionalMultiArray<typename Func::value_type,Func,RangeTypes...>,
|
||||||
|
RangeTypes...> >
|
||||||
|
{
|
||||||
|
typedef FunctionalMultiArray<typename Func::value_type,Func,RangeTypes...> FMA;
|
||||||
|
std::shared_ptr<MapRangeFactory<FMA,RangeTypes...>> mrfptr;
|
||||||
|
if(Func::FISSTATIC){
|
||||||
|
FMA fma(ranges...);
|
||||||
|
mrfptr = std::make_shared<MapRangeFactory<FMA,RangeTypes...> >( fma, ranges... );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FMA fma(ranges...,f);
|
||||||
|
mrfptr = std::make_shared<MapRangeFactory<FMA,RangeTypes...> >( fma, ranges... );
|
||||||
|
}
|
||||||
|
return std::dynamic_pointer_cast<MapRange<FMA,RangeTypes...> >( mrfptr->create() );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Func, class... IndexTypes>
|
||||||
|
auto mkMapI(const std::shared_ptr<Func>& f, std::shared_ptr<IndexTypes>... indices)
|
||||||
|
-> decltype( getIndex( mkMapR( f, indices->range()... ) ) )
|
||||||
|
{
|
||||||
|
auto mi = getIndex( mkMapR( f, indices->range()... ) );
|
||||||
|
(*mi)(indices...);
|
||||||
|
return mi;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... RangeTypes>
|
||||||
|
auto mkMulti(std::tuple<std::shared_ptr<RangeTypes>...> rangesTuple)
|
||||||
|
-> MultiRange<RangeTypes...>
|
||||||
|
{
|
||||||
|
MultiRangeFactory<RangeTypes...> mrf( rangesTuple );
|
||||||
|
return std::dynamic_pointer_cast<MultiRange<RangeTypes...> >( mrf.create() );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class RangeFactory>
|
||||||
|
auto createExplicit(RangeFactory& rf)
|
||||||
|
-> std::shared_ptr<typename RangeFactory::oType>
|
||||||
|
{
|
||||||
|
return std::dynamic_pointer_cast<typename RangeFactory::oType>( rf.create() );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class RangeFactory>
|
||||||
|
auto createExplicit(std::shared_ptr<RangeFactory> rfp)
|
||||||
|
-> std::shared_ptr<typename RangeFactory::oType>
|
||||||
|
{
|
||||||
|
return std::dynamic_pointer_cast<typename RangeFactory::oType>( rfp->create() );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Range>
|
||||||
|
auto createRange(const std::vector<char>& cvec)
|
||||||
|
-> std::shared_ptr<Range>
|
||||||
|
{
|
||||||
|
const char* dp = cvec.data();
|
||||||
|
auto ff = createRangeFactory(&dp);
|
||||||
|
auto rbptr = ff->create();
|
||||||
|
assert(rbptr->spaceType() == Range::STYPE);
|
||||||
|
// CATCH CAST ERROR HERE !!!
|
||||||
|
return std::dynamic_pointer_cast<Range>( rbptr );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t N, class MArray>
|
||||||
|
auto rptr(const MArray& ma)
|
||||||
|
-> decltype(ma.template getRangePtr<N>())
|
||||||
|
{
|
||||||
|
return ma.template getRangePtr<N>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -59,132 +59,6 @@ namespace MultiArrayTools
|
||||||
auto prtr(const MArray& ma)
|
auto prtr(const MArray& ma)
|
||||||
-> decltype(ma.template getRangePtr<N>());
|
-> decltype(ma.template getRangePtr<N>());
|
||||||
|
|
||||||
template <class IndexType>
|
|
||||||
inline void For(const std::shared_ptr<IndexType>& ind, const std::function<void(void)>& ll);
|
|
||||||
|
|
||||||
template <class Index>
|
|
||||||
inline auto mkOp(const std::shared_ptr<Index>& i)
|
|
||||||
-> decltype(std::declval<FunctionalMultiArray<typename Index::MetaType,
|
|
||||||
identity<typename Index::MetaType>,typename Index::RangeType> >
|
|
||||||
().exec(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================= *
|
|
||||||
* --- TEMPLATE CODE --- *
|
|
||||||
* ========================= */
|
|
||||||
|
|
||||||
namespace MultiArrayTools
|
|
||||||
{
|
|
||||||
template <typename... T>
|
|
||||||
std::ostream& operator<<(std::ostream& out, const std::tuple<T...>& tp)
|
|
||||||
{
|
|
||||||
PackNum<sizeof...(T)-1>::printTuple(out, tp);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class RangeType>
|
|
||||||
auto getIndex(std::shared_ptr<RangeType> range)
|
|
||||||
-> std::shared_ptr<typename RangeType::IndexType>
|
|
||||||
{
|
|
||||||
return std::make_shared<typename RangeType::IndexType>(range);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class RangeType>
|
|
||||||
auto getIndex()
|
|
||||||
-> std::shared_ptr<typename RangeType::IndexType>
|
|
||||||
{
|
|
||||||
static_assert( RangeType::defaultable,
|
|
||||||
/*typeid(typename RangeType).name() + */" is not defaultable" );
|
|
||||||
static auto f = RangeType::factory();
|
|
||||||
static auto r = std::dynamic_pointer_cast<RangeType>( f.create() );
|
|
||||||
return std::make_shared<typename RangeType::IndexType>(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... RangeTypes>
|
|
||||||
auto mkMulti(std::shared_ptr<RangeTypes>... ranges)
|
|
||||||
-> std::shared_ptr<MultiRange<RangeTypes...> >
|
|
||||||
{
|
|
||||||
MultiRangeFactory<RangeTypes...> mrf( ranges... );
|
|
||||||
return std::dynamic_pointer_cast<MultiRange<RangeTypes...> >( mrf.create() );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... IndexTypes>
|
|
||||||
auto mkMIndex(std::shared_ptr<IndexTypes>... indices)
|
|
||||||
-> decltype( getIndex( mkMulti( indices->range()... ) ) )
|
|
||||||
{
|
|
||||||
auto mi = getIndex( mkMulti( indices->range()... ) );
|
|
||||||
(*mi)( indices... );
|
|
||||||
return mi;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Func, class... RangeTypes>
|
|
||||||
auto mkMapR(const std::shared_ptr<Func>& f, std::shared_ptr<RangeTypes>... ranges)
|
|
||||||
-> std::shared_ptr<MapRange<FunctionalMultiArray<typename Func::value_type,Func,RangeTypes...>,
|
|
||||||
RangeTypes...> >
|
|
||||||
{
|
|
||||||
typedef FunctionalMultiArray<typename Func::value_type,Func,RangeTypes...> FMA;
|
|
||||||
std::shared_ptr<MapRangeFactory<FMA,RangeTypes...>> mrfptr;
|
|
||||||
if(Func::FISSTATIC){
|
|
||||||
FMA fma(ranges...);
|
|
||||||
mrfptr = std::make_shared<MapRangeFactory<FMA,RangeTypes...> >( fma, ranges... );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
FMA fma(ranges...,f);
|
|
||||||
mrfptr = std::make_shared<MapRangeFactory<FMA,RangeTypes...> >( fma, ranges... );
|
|
||||||
}
|
|
||||||
return std::dynamic_pointer_cast<MapRange<FMA,RangeTypes...> >( mrfptr->create() );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Func, class... IndexTypes>
|
|
||||||
auto mkMapI(const std::shared_ptr<Func>& f, std::shared_ptr<IndexTypes>... indices)
|
|
||||||
-> decltype( getIndex( mkMapR( f, indices->range()... ) ) )
|
|
||||||
{
|
|
||||||
auto mi = getIndex( mkMapR( f, indices->range()... ) );
|
|
||||||
(*mi)(indices...);
|
|
||||||
return mi;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... RangeTypes>
|
|
||||||
auto mkMulti(std::tuple<std::shared_ptr<RangeTypes>...> rangesTuple)
|
|
||||||
-> MultiRange<RangeTypes...>
|
|
||||||
{
|
|
||||||
MultiRangeFactory<RangeTypes...> mrf( rangesTuple );
|
|
||||||
return std::dynamic_pointer_cast<MultiRange<RangeTypes...> >( mrf.create() );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class RangeFactory>
|
|
||||||
auto createExplicit(RangeFactory& rf)
|
|
||||||
-> std::shared_ptr<typename RangeFactory::oType>
|
|
||||||
{
|
|
||||||
return std::dynamic_pointer_cast<typename RangeFactory::oType>( rf.create() );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class RangeFactory>
|
|
||||||
auto createExplicit(std::shared_ptr<RangeFactory> rfp)
|
|
||||||
-> std::shared_ptr<typename RangeFactory::oType>
|
|
||||||
{
|
|
||||||
return std::dynamic_pointer_cast<typename RangeFactory::oType>( rfp->create() );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Range>
|
|
||||||
auto createRange(const std::vector<char>& cvec)
|
|
||||||
-> std::shared_ptr<Range>
|
|
||||||
{
|
|
||||||
const char* dp = cvec.data();
|
|
||||||
auto ff = createRangeFactory(&dp);
|
|
||||||
auto rbptr = ff->create();
|
|
||||||
assert(rbptr->spaceType() == Range::STYPE);
|
|
||||||
// CATCH CAST ERROR HERE !!!
|
|
||||||
return std::dynamic_pointer_cast<Range>( rbptr );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t N, class MArray>
|
|
||||||
auto rptr(const MArray& ma)
|
|
||||||
-> decltype(ma.template getRangePtr<N>())
|
|
||||||
{
|
|
||||||
return ma.template getRangePtr<N>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class IndexType>
|
template <class IndexType>
|
||||||
inline void For(const std::shared_ptr<IndexType>& ind, const std::function<void(void)>& ll)
|
inline void For(const std::shared_ptr<IndexType>& ind, const std::function<void(void)>& ll)
|
||||||
{
|
{
|
||||||
|
@ -193,6 +67,7 @@ namespace MultiArrayTools
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class Index>
|
template <class Index>
|
||||||
inline auto mkOp(const std::shared_ptr<Index>& i)
|
inline auto mkOp(const std::shared_ptr<Index>& i)
|
||||||
-> decltype(std::declval<FunctionalMultiArray<typename Index::MetaType,
|
-> decltype(std::declval<FunctionalMultiArray<typename Index::MetaType,
|
||||||
|
@ -207,4 +82,5 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
512
src/include/map_range.cc.h
Normal file
512
src/include/map_range.cc.h
Normal file
|
@ -0,0 +1,512 @@
|
||||||
|
|
||||||
|
#include "map_range.h"
|
||||||
|
|
||||||
|
namespace MultiArrayTools
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
using namespace MultiArrayHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************
|
||||||
|
* OpExpr *
|
||||||
|
**************/
|
||||||
|
|
||||||
|
template <class MapF, class IndexPack, class Expr>
|
||||||
|
OpExpr<MapF,IndexPack,Expr>::OpExpr(const MapF& mapf, const IndexPack& ipack,
|
||||||
|
const std::shared_ptr<OIType>& oind, size_t step, Expr ex) :
|
||||||
|
mIndPtr(oind.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()),
|
||||||
|
mStep(step), mExpr( std::forward<Expr>(ex) ),
|
||||||
|
mOp(mkMapOp(mapf, ipack)),
|
||||||
|
//mExt(ex.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )))
|
||||||
|
mExt( mOp.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ) ).extend
|
||||||
|
( ex.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ) ) ) )
|
||||||
|
{
|
||||||
|
assert(mIndPtr != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class IndexPack, class Expr>
|
||||||
|
inline void OpExpr<MapF,IndexPack,Expr>::operator()(size_t mlast,
|
||||||
|
ExtType last) const
|
||||||
|
{
|
||||||
|
constexpr size_t NEXT = Op::SIZE;
|
||||||
|
const ExtType nxpos = last;
|
||||||
|
const size_t pos = mIndPtr->posAt( mOp.get( nxpos ) );
|
||||||
|
//VCHECK(pos);
|
||||||
|
const ExtType npos = last + mExt*pos;
|
||||||
|
//VCHECK(npos.next().next().val());
|
||||||
|
const size_t mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos);
|
||||||
|
mExpr(mnpos, Getter<NEXT>::template getX<ExtType>( npos ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class IndexPack, class Expr>
|
||||||
|
inline void OpExpr<MapF,IndexPack,Expr>::operator()(size_t mlast) const
|
||||||
|
{
|
||||||
|
const ExtType last;
|
||||||
|
constexpr size_t NEXT = Op::SIZE;
|
||||||
|
const ExtType nxpos = last;
|
||||||
|
const size_t pos = mIndPtr->posAt( mOp.get( nxpos ) );
|
||||||
|
const ExtType npos = last + mExt*pos;
|
||||||
|
const size_t mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos);
|
||||||
|
mExpr(mnpos, Getter<NEXT>::template getX<ExtType>( npos ));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class IndexPack, class Expr>
|
||||||
|
auto OpExpr<MapF,IndexPack,Expr>::rootSteps(std::intptr_t iPtrNum) const
|
||||||
|
-> ExtType
|
||||||
|
{
|
||||||
|
return mOp.rootSteps(iPtrNum).extend( mExpr.rootSteps(iPtrNum) );
|
||||||
|
//return mExpr.rootSteps(iPtrNum).extend( mOp.rootSteps(iPtrNum) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -> define in range_base.cc
|
||||||
|
//std::shared_ptr<RangeFactoryBase> mkMULTI(const char** dp);
|
||||||
|
|
||||||
|
/******************
|
||||||
|
* MapIndex *
|
||||||
|
******************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
MapIndex<MapF,Indices...>::MapIndex(const MapIndex<MapF,Indices...>& in) :
|
||||||
|
IndexInterface<std::tuple<typename Indices::MetaType...> >(in)
|
||||||
|
{
|
||||||
|
RPackNum<sizeof...(Indices)-1>::copy(mIPack, in);
|
||||||
|
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::operator=(const MapIndex<MapF,Indices...>& in)
|
||||||
|
{
|
||||||
|
IndexI::operator=(in);
|
||||||
|
RPackNum<sizeof...(Indices)-1>::copy(mIPack, in);
|
||||||
|
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
template <class MRange>
|
||||||
|
MapIndex<MapF,Indices...>::MapIndex(const std::shared_ptr<MRange>& range) :
|
||||||
|
IndexInterface<MapIndex<MapF,Indices...>,std::tuple<typename Indices::MetaType...> >(range, 0)
|
||||||
|
{
|
||||||
|
RPackNum<sizeof...(Indices)-1>::construct(mIPack, *range);
|
||||||
|
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
||||||
|
std::get<sizeof...(Indices)>(mBlockSizes) = 1;
|
||||||
|
RPackNum<sizeof...(Indices)-1>::initBlockSizes(mBlockSizes, mIPack); // has one more element!
|
||||||
|
mOutIndex = std::make_shared<OIType>
|
||||||
|
( std::dynamic_pointer_cast<RangeType>( IB::mRangePtr )->outRange()->begin() );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
template <size_t DIR>
|
||||||
|
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::up()
|
||||||
|
{
|
||||||
|
static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices");
|
||||||
|
IB::mPos += RPackNum<sizeof...(Indices)-DIR-1>::blockSize( mIPack );
|
||||||
|
RPackNum<DIR>::pp( mIPack );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
template <size_t DIR>
|
||||||
|
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::down()
|
||||||
|
{
|
||||||
|
static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices");
|
||||||
|
IB::mPos -= RPackNum<sizeof...(Indices)-DIR-1>::blockSize( mIPack );
|
||||||
|
RPackNum<DIR>::mm( mIPack );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
template <size_t N>
|
||||||
|
auto MapIndex<MapF,Indices...>::get() const -> decltype( *std::get<N>( mIPack ) )&
|
||||||
|
{
|
||||||
|
return *std::get<N>(mIPack);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
template <size_t N>
|
||||||
|
auto MapIndex<MapF,Indices...>::getPtr() const -> decltype( std::get<N>( mIPack ) )&
|
||||||
|
{
|
||||||
|
return std::get<N>(mIPack);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
auto MapIndex<MapF,Indices...>::outIndex() const -> std::shared_ptr<OIType>
|
||||||
|
{
|
||||||
|
return mOutIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::operator()(std::shared_ptr<Indices>&... indices)
|
||||||
|
{
|
||||||
|
RPackNum<sizeof...(Indices)-1>::swapIndices(mIPack, indices...);
|
||||||
|
RPackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, IB::mPos);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
IndexType MapIndex<MapF,Indices...>::type() const
|
||||||
|
{
|
||||||
|
return IndexType::MULTI;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::operator=(size_t pos)
|
||||||
|
{
|
||||||
|
IB::mPos = pos;
|
||||||
|
RPackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, pos);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::operator++()
|
||||||
|
{
|
||||||
|
RPackNum<sizeof...(Indices)-1>::pp( mIPack );
|
||||||
|
++IB::mPos;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::operator--()
|
||||||
|
{
|
||||||
|
RPackNum<sizeof...(Indices)-1>::mm( mIPack );
|
||||||
|
--IB::mPos;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
int MapIndex<MapF,Indices...>::pp(std::intptr_t idxPtrNum)
|
||||||
|
{
|
||||||
|
int tmp = RPackNum<sizeof...(Indices)-1>::pp(mIPack, mBlockSizes, idxPtrNum);
|
||||||
|
IB::mPos += tmp;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
int MapIndex<MapF,Indices...>::mm(std::intptr_t idxPtrNum)
|
||||||
|
{
|
||||||
|
int tmp = RPackNum<sizeof...(Indices)-1>::mm(mIPack, mBlockSizes, idxPtrNum);
|
||||||
|
IB::mPos -= tmp;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
std::string MapIndex<MapF,Indices...>::stringMeta() const
|
||||||
|
{
|
||||||
|
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr )->stringMeta(IB::mPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
typename MapIndex<MapF,Indices...>::MetaType MapIndex<MapF,Indices...>::meta() const
|
||||||
|
{
|
||||||
|
MetaType metaTuple;
|
||||||
|
RPackNum<sizeof...(Indices)-1>::getMetaPos(metaTuple, mIPack);
|
||||||
|
return metaTuple;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::at(const MetaType& metaPos)
|
||||||
|
{
|
||||||
|
RPackNum<sizeof...(Indices)-1>::setMeta(mIPack, metaPos);
|
||||||
|
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
size_t MapIndex<MapF,Indices...>::dim() const
|
||||||
|
{
|
||||||
|
return sizeof...(Indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
bool MapIndex<MapF,Indices...>::first() const
|
||||||
|
{
|
||||||
|
return IB::mPos == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
bool MapIndex<MapF,Indices...>::last() const
|
||||||
|
{
|
||||||
|
return IB::mPos == IB::mMax - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
std::shared_ptr<typename MapIndex<MapF,Indices...>::RangeType>
|
||||||
|
MapIndex<MapF,Indices...>::range() const
|
||||||
|
{
|
||||||
|
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
template <size_t N>
|
||||||
|
auto MapIndex<MapF,Indices...>::getPtr() -> decltype( std::get<N>( mIPack ) )&
|
||||||
|
{
|
||||||
|
return std::get<N>(mIPack);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
size_t MapIndex<MapF,Indices...>::getStepSize(size_t n) const
|
||||||
|
{
|
||||||
|
if(n >= sizeof...(Indices)){
|
||||||
|
assert(0);
|
||||||
|
// throw !!
|
||||||
|
}
|
||||||
|
return mBlockSizes[n+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
std::string MapIndex<MapF,Indices...>::id() const
|
||||||
|
{
|
||||||
|
return std::string("mul") + std::to_string(IB::mId);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
void MapIndex<MapF,Indices...>::print(size_t offset) const
|
||||||
|
{
|
||||||
|
if(offset == 0){
|
||||||
|
std::cout << " === " << std::endl;
|
||||||
|
}
|
||||||
|
for(size_t j = 0; j != offset; ++j) { std::cout << "\t"; }
|
||||||
|
std::cout << id() << "[" << reinterpret_cast<std::intptr_t>(this)
|
||||||
|
<< "]" << "(" << IB::mRangePtr << "): " << meta() << std::endl;
|
||||||
|
RPackNum<sizeof...(Indices)-1>::printIndex(mIPack, offset+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
template <class Exprs>
|
||||||
|
auto MapIndex<MapF,Indices...>::ifor(size_t step, Exprs exs) const
|
||||||
|
-> decltype(RPackNum<sizeof...(Indices)-1>::mkForh
|
||||||
|
(step, mIPack, mBlockSizes, OpExpr<MapF,IndexPack,Exprs>
|
||||||
|
( range()->map(), mIPack, mOutIndex, step, exs ) ) )
|
||||||
|
{
|
||||||
|
return RPackNum<sizeof...(Indices)-1>::mkForh
|
||||||
|
(step, mIPack, mBlockSizes, OpExpr<MapF,IndexPack,Exprs>
|
||||||
|
( range()->map(), mIPack, mOutIndex, step, exs ) );
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
template <class MapF, class... Indices>
|
||||||
|
template <class Exprs>
|
||||||
|
auto MapIndex<MapF,Indices...>::iforh(Exprs exs) const
|
||||||
|
-> decltype(RPackNum<sizeof...(Indices)-1>::mkForh(mIPack, exs))
|
||||||
|
{
|
||||||
|
return RPackNum<sizeof...(Indices)-1>::mkForh(mIPack, exs);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/*************************
|
||||||
|
* MapRangeFactory *
|
||||||
|
*************************/
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
MapRangeFactory<MapF,Ranges...>::MapRangeFactory(const MapF& mapf, const std::shared_ptr<Ranges>&... rs)
|
||||||
|
{
|
||||||
|
mProd = std::shared_ptr< MapRange<MapF,Ranges...> >( new MapRange<MapF,Ranges...>( mapf, rs... ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
MapRangeFactory<MapF,Ranges...>::MapRangeFactory(const MapF& mapf, const typename MapRange<MapF,Ranges...>::Space& st)
|
||||||
|
{
|
||||||
|
mProd = std::shared_ptr< MapRange<MapF,Ranges...> >( new MapRange<MapF,Ranges...>( mapf, st ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
std::shared_ptr<RangeBase> MapRangeFactory<MapF,Ranges...>::create()
|
||||||
|
{
|
||||||
|
mProd = checkIfCreated( std::dynamic_pointer_cast<oType>( mProd )->mSpace );
|
||||||
|
setSelf();
|
||||||
|
return mProd;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
std::shared_ptr<RangeBase> MapRangeFactory<MapF,Ranges...>::checkIfCreated(const std::tuple<std::shared_ptr<Ranges>...>& ptp)
|
||||||
|
{
|
||||||
|
std::shared_ptr<RangeBase> out;
|
||||||
|
bool check = false;
|
||||||
|
for(auto& x: MapRangeFactoryProductMap::mAleadyCreated){
|
||||||
|
if(x.second.size() == sizeof...(Ranges)){
|
||||||
|
check = RPackNum<sizeof...(Ranges)-1>::checkIfCreated(ptp, x.second);
|
||||||
|
if(check){
|
||||||
|
out = x.first;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(not check){
|
||||||
|
std::vector<std::intptr_t> pv(sizeof...(Ranges));
|
||||||
|
RPackNum<sizeof...(Ranges)-1>::RangesToVec(ptp, pv);
|
||||||
|
pv.push_back( reinterpret_cast<std::intptr_t>
|
||||||
|
( &std::dynamic_pointer_cast<oType>( mProd )->mMapf ) );
|
||||||
|
MapRangeFactoryProductMap::mAleadyCreated[mProd] = pv;
|
||||||
|
out = mProd;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************
|
||||||
|
* MapRange *
|
||||||
|
******************/
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
void MapRange<MapF,Ranges...>::mkOutRange()
|
||||||
|
{
|
||||||
|
//FunctionalMultiArray<typename MapF::value_type,MapF,Ranges...> fma(mSpace, mMapf);
|
||||||
|
std::map<typename MapF::value_type,size_t> mult;
|
||||||
|
for(auto ii = mMapf.begin(); ii.max() != ii.pos(); ++ii) {
|
||||||
|
mult[mMapf[ii]]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<typename MapF::value_type> outmeta(mult.size());
|
||||||
|
std::vector<size_t> outmult(mult.size());
|
||||||
|
|
||||||
|
size_t cnt = 0;
|
||||||
|
for(auto& x: mult){
|
||||||
|
outmeta[cnt] = x.first;
|
||||||
|
outmult[cnt] = x.second;
|
||||||
|
++cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
ORFType orf(outmeta);
|
||||||
|
mOutRange = std::dynamic_pointer_cast<ORType>( orf.create() );
|
||||||
|
mMapMult = MultiArray<size_t,ORType>( mOutRange, outmult );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
MapRange<MapF,Ranges...>::MapRange(const MapF& mapf, const std::shared_ptr<Ranges>&... rs) :
|
||||||
|
mSpace(std::make_tuple(rs...)),
|
||||||
|
mMapf(mapf)
|
||||||
|
{
|
||||||
|
mkOutRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
MapRange<MapF,Ranges...>::MapRange(const MapF& mapf, const Space& space) :
|
||||||
|
mSpace( space ),
|
||||||
|
mMapf(mapf)
|
||||||
|
{
|
||||||
|
mkOutRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
template <size_t N>
|
||||||
|
auto MapRange<MapF,Ranges...>::get() const -> decltype( *std::get<N>( mSpace ) )&
|
||||||
|
{
|
||||||
|
return *std::get<N>(mSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
template <size_t N>
|
||||||
|
auto MapRange<MapF,Ranges...>::getPtr() const -> decltype( std::get<N>( mSpace ) )&
|
||||||
|
{
|
||||||
|
return std::get<N>(mSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
auto MapRange<MapF,Ranges...>::outRange() const -> std::shared_ptr<ORType>
|
||||||
|
{
|
||||||
|
return mOutRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
const MapF& MapRange<MapF,Ranges...>::map() const
|
||||||
|
{
|
||||||
|
return mMapf;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
size_t MapRange<MapF,Ranges...>::dim() const
|
||||||
|
{
|
||||||
|
return sdim;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
size_t MapRange<MapF,Ranges...>::size() const
|
||||||
|
{
|
||||||
|
return mOutRange->size();
|
||||||
|
//return RPackNum<sizeof...(Ranges)-1>::getSize(mSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
SpaceType MapRange<MapF,Ranges...>::spaceType() const
|
||||||
|
{
|
||||||
|
return SpaceType::ANY;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
const typename MapRange<MapF,Ranges...>::Space& MapRange<MapF,Ranges...>::space() const
|
||||||
|
{
|
||||||
|
return mSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
std::string MapRange<MapF,Ranges...>::stringMeta(size_t pos) const
|
||||||
|
{
|
||||||
|
auto i = begin();
|
||||||
|
i = pos;
|
||||||
|
return "[ " + RPackNum<sizeof...(Ranges)-1>::metaTupleToString(i.meta()) + " ]";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
std::vector<char> MapRange<MapF,Ranges...>::data() const
|
||||||
|
{
|
||||||
|
DataHeader h;
|
||||||
|
h.spaceType = static_cast<int>( SpaceType::ANY );
|
||||||
|
h.metaSize = sizeof...(Ranges);
|
||||||
|
h.multiple = 1;
|
||||||
|
std::vector<char> out;
|
||||||
|
//out.reserve(h.metaSize + sizeof(DataHeader));
|
||||||
|
char* hcp = reinterpret_cast<char*>(&h);
|
||||||
|
out.insert(out.end(), hcp, hcp + sizeof(DataHeader));
|
||||||
|
RPackNum<sizeof...(Ranges)-1>::fillRangeDataVec(out, mSpace);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
typename MapRange<MapF,Ranges...>::IndexType MapRange<MapF,Ranges...>::begin() const
|
||||||
|
{
|
||||||
|
MapIndex<MapF,typename Ranges::IndexType...>
|
||||||
|
i( std::dynamic_pointer_cast<MapRange<MapF,Ranges...> >
|
||||||
|
( std::shared_ptr<RangeBase>( RB::mThis ) ) );
|
||||||
|
i = 0;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
typename MapRange<MapF,Ranges...>::IndexType MapRange<MapF,Ranges...>::end() const
|
||||||
|
{
|
||||||
|
MapIndex<MapF,typename Ranges::IndexType...>
|
||||||
|
i( std::dynamic_pointer_cast<MapRange<MapF,Ranges...> >
|
||||||
|
( std::shared_ptr<RangeBase>( RB::mThis )) );
|
||||||
|
i = size();
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
auto MapRange<MapF,Ranges...>::mapMultiplicity() const
|
||||||
|
-> const MultiArray<size_t,ORType>&
|
||||||
|
{
|
||||||
|
return mMapMult;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
auto MapRange<MapF,Ranges...>::explMapMultiplicity() const
|
||||||
|
-> MultiArray<size_t,MapRange>
|
||||||
|
{
|
||||||
|
auto tmp = mMapMult;
|
||||||
|
return tmp.format( std::dynamic_pointer_cast<MapRange<MapF,Ranges...> >
|
||||||
|
( std::shared_ptr<RangeBase>( RB::mThis )) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MapF, class... Ranges>
|
||||||
|
template <class... ERanges>
|
||||||
|
auto MapRange<MapF,Ranges...>::cat(const std::shared_ptr<MapRange<ERanges...> >& erange)
|
||||||
|
-> std::shared_ptr<MapRange<Ranges...,ERanges...> >
|
||||||
|
{
|
||||||
|
auto crange = std::tuple_cat(mSpace, erange->space());
|
||||||
|
MapRangeFactory<Ranges...,ERanges...> rf(crange);
|
||||||
|
return std::dynamic_pointer_cast<MapRange<Ranges...,ERanges...> >(rf.create());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -284,518 +284,5 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================= *
|
|
||||||
* --- TEMPLATE CODE --- *
|
|
||||||
* ========================= */
|
|
||||||
|
|
||||||
namespace MultiArrayTools
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
using namespace MultiArrayHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************
|
|
||||||
* OpExpr *
|
|
||||||
**************/
|
|
||||||
|
|
||||||
template <class MapF, class IndexPack, class Expr>
|
|
||||||
OpExpr<MapF,IndexPack,Expr>::OpExpr(const MapF& mapf, const IndexPack& ipack,
|
|
||||||
const std::shared_ptr<OIType>& oind, size_t step, Expr ex) :
|
|
||||||
mIndPtr(oind.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()),
|
|
||||||
mStep(step), mExpr( std::forward<Expr>(ex) ),
|
|
||||||
mOp(mkMapOp(mapf, ipack)),
|
|
||||||
//mExt(ex.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )))
|
|
||||||
mExt( mOp.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ) ).extend
|
|
||||||
( ex.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ) ) ) )
|
|
||||||
{
|
|
||||||
assert(mIndPtr != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class IndexPack, class Expr>
|
|
||||||
inline void OpExpr<MapF,IndexPack,Expr>::operator()(size_t mlast,
|
|
||||||
ExtType last) const
|
|
||||||
{
|
|
||||||
constexpr size_t NEXT = Op::SIZE;
|
|
||||||
const ExtType nxpos = last;
|
|
||||||
const size_t pos = mIndPtr->posAt( mOp.get( nxpos ) );
|
|
||||||
//VCHECK(pos);
|
|
||||||
const ExtType npos = last + mExt*pos;
|
|
||||||
//VCHECK(npos.next().next().val());
|
|
||||||
const size_t mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos);
|
|
||||||
mExpr(mnpos, Getter<NEXT>::template getX<ExtType>( npos ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class IndexPack, class Expr>
|
|
||||||
inline void OpExpr<MapF,IndexPack,Expr>::operator()(size_t mlast) const
|
|
||||||
{
|
|
||||||
const ExtType last;
|
|
||||||
constexpr size_t NEXT = Op::SIZE;
|
|
||||||
const ExtType nxpos = last;
|
|
||||||
const size_t pos = mIndPtr->posAt( mOp.get( nxpos ) );
|
|
||||||
const ExtType npos = last + mExt*pos;
|
|
||||||
const size_t mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos);
|
|
||||||
mExpr(mnpos, Getter<NEXT>::template getX<ExtType>( npos ));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class IndexPack, class Expr>
|
|
||||||
auto OpExpr<MapF,IndexPack,Expr>::rootSteps(std::intptr_t iPtrNum) const
|
|
||||||
-> ExtType
|
|
||||||
{
|
|
||||||
return mOp.rootSteps(iPtrNum).extend( mExpr.rootSteps(iPtrNum) );
|
|
||||||
//return mExpr.rootSteps(iPtrNum).extend( mOp.rootSteps(iPtrNum) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -> define in range_base.cc
|
|
||||||
//std::shared_ptr<RangeFactoryBase> mkMULTI(const char** dp);
|
|
||||||
|
|
||||||
/******************
|
|
||||||
* MapIndex *
|
|
||||||
******************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
MapIndex<MapF,Indices...>::MapIndex(const MapIndex<MapF,Indices...>& in) :
|
|
||||||
IndexInterface<std::tuple<typename Indices::MetaType...> >(in)
|
|
||||||
{
|
|
||||||
RPackNum<sizeof...(Indices)-1>::copy(mIPack, in);
|
|
||||||
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::operator=(const MapIndex<MapF,Indices...>& in)
|
|
||||||
{
|
|
||||||
IndexI::operator=(in);
|
|
||||||
RPackNum<sizeof...(Indices)-1>::copy(mIPack, in);
|
|
||||||
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
template <class MRange>
|
|
||||||
MapIndex<MapF,Indices...>::MapIndex(const std::shared_ptr<MRange>& range) :
|
|
||||||
IndexInterface<MapIndex<MapF,Indices...>,std::tuple<typename Indices::MetaType...> >(range, 0)
|
|
||||||
{
|
|
||||||
RPackNum<sizeof...(Indices)-1>::construct(mIPack, *range);
|
|
||||||
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
|
||||||
std::get<sizeof...(Indices)>(mBlockSizes) = 1;
|
|
||||||
RPackNum<sizeof...(Indices)-1>::initBlockSizes(mBlockSizes, mIPack); // has one more element!
|
|
||||||
mOutIndex = std::make_shared<OIType>
|
|
||||||
( std::dynamic_pointer_cast<RangeType>( IB::mRangePtr )->outRange()->begin() );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
template <size_t DIR>
|
|
||||||
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::up()
|
|
||||||
{
|
|
||||||
static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices");
|
|
||||||
IB::mPos += RPackNum<sizeof...(Indices)-DIR-1>::blockSize( mIPack );
|
|
||||||
RPackNum<DIR>::pp( mIPack );
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
template <size_t DIR>
|
|
||||||
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::down()
|
|
||||||
{
|
|
||||||
static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices");
|
|
||||||
IB::mPos -= RPackNum<sizeof...(Indices)-DIR-1>::blockSize( mIPack );
|
|
||||||
RPackNum<DIR>::mm( mIPack );
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
template <size_t N>
|
|
||||||
auto MapIndex<MapF,Indices...>::get() const -> decltype( *std::get<N>( mIPack ) )&
|
|
||||||
{
|
|
||||||
return *std::get<N>(mIPack);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
template <size_t N>
|
|
||||||
auto MapIndex<MapF,Indices...>::getPtr() const -> decltype( std::get<N>( mIPack ) )&
|
|
||||||
{
|
|
||||||
return std::get<N>(mIPack);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
auto MapIndex<MapF,Indices...>::outIndex() const -> std::shared_ptr<OIType>
|
|
||||||
{
|
|
||||||
return mOutIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::operator()(std::shared_ptr<Indices>&... indices)
|
|
||||||
{
|
|
||||||
RPackNum<sizeof...(Indices)-1>::swapIndices(mIPack, indices...);
|
|
||||||
RPackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, IB::mPos);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
IndexType MapIndex<MapF,Indices...>::type() const
|
|
||||||
{
|
|
||||||
return IndexType::MULTI;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::operator=(size_t pos)
|
|
||||||
{
|
|
||||||
IB::mPos = pos;
|
|
||||||
RPackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, pos);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::operator++()
|
|
||||||
{
|
|
||||||
RPackNum<sizeof...(Indices)-1>::pp( mIPack );
|
|
||||||
++IB::mPos;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::operator--()
|
|
||||||
{
|
|
||||||
RPackNum<sizeof...(Indices)-1>::mm( mIPack );
|
|
||||||
--IB::mPos;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
int MapIndex<MapF,Indices...>::pp(std::intptr_t idxPtrNum)
|
|
||||||
{
|
|
||||||
int tmp = RPackNum<sizeof...(Indices)-1>::pp(mIPack, mBlockSizes, idxPtrNum);
|
|
||||||
IB::mPos += tmp;
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
int MapIndex<MapF,Indices...>::mm(std::intptr_t idxPtrNum)
|
|
||||||
{
|
|
||||||
int tmp = RPackNum<sizeof...(Indices)-1>::mm(mIPack, mBlockSizes, idxPtrNum);
|
|
||||||
IB::mPos -= tmp;
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
std::string MapIndex<MapF,Indices...>::stringMeta() const
|
|
||||||
{
|
|
||||||
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr )->stringMeta(IB::mPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
typename MapIndex<MapF,Indices...>::MetaType MapIndex<MapF,Indices...>::meta() const
|
|
||||||
{
|
|
||||||
MetaType metaTuple;
|
|
||||||
RPackNum<sizeof...(Indices)-1>::getMetaPos(metaTuple, mIPack);
|
|
||||||
return metaTuple;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::at(const MetaType& metaPos)
|
|
||||||
{
|
|
||||||
RPackNum<sizeof...(Indices)-1>::setMeta(mIPack, metaPos);
|
|
||||||
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
size_t MapIndex<MapF,Indices...>::dim() const
|
|
||||||
{
|
|
||||||
return sizeof...(Indices);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
bool MapIndex<MapF,Indices...>::first() const
|
|
||||||
{
|
|
||||||
return IB::mPos == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
bool MapIndex<MapF,Indices...>::last() const
|
|
||||||
{
|
|
||||||
return IB::mPos == IB::mMax - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
std::shared_ptr<typename MapIndex<MapF,Indices...>::RangeType>
|
|
||||||
MapIndex<MapF,Indices...>::range() const
|
|
||||||
{
|
|
||||||
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
template <size_t N>
|
|
||||||
auto MapIndex<MapF,Indices...>::getPtr() -> decltype( std::get<N>( mIPack ) )&
|
|
||||||
{
|
|
||||||
return std::get<N>(mIPack);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
size_t MapIndex<MapF,Indices...>::getStepSize(size_t n) const
|
|
||||||
{
|
|
||||||
if(n >= sizeof...(Indices)){
|
|
||||||
assert(0);
|
|
||||||
// throw !!
|
|
||||||
}
|
|
||||||
return mBlockSizes[n+1];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
std::string MapIndex<MapF,Indices...>::id() const
|
|
||||||
{
|
|
||||||
return std::string("mul") + std::to_string(IB::mId);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
void MapIndex<MapF,Indices...>::print(size_t offset) const
|
|
||||||
{
|
|
||||||
if(offset == 0){
|
|
||||||
std::cout << " === " << std::endl;
|
|
||||||
}
|
|
||||||
for(size_t j = 0; j != offset; ++j) { std::cout << "\t"; }
|
|
||||||
std::cout << id() << "[" << reinterpret_cast<std::intptr_t>(this)
|
|
||||||
<< "]" << "(" << IB::mRangePtr << "): " << meta() << std::endl;
|
|
||||||
RPackNum<sizeof...(Indices)-1>::printIndex(mIPack, offset+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
template <class Exprs>
|
|
||||||
auto MapIndex<MapF,Indices...>::ifor(size_t step, Exprs exs) const
|
|
||||||
-> decltype(RPackNum<sizeof...(Indices)-1>::mkForh
|
|
||||||
(step, mIPack, mBlockSizes, OpExpr<MapF,IndexPack,Exprs>
|
|
||||||
( range()->map(), mIPack, mOutIndex, step, exs ) ) )
|
|
||||||
{
|
|
||||||
return RPackNum<sizeof...(Indices)-1>::mkForh
|
|
||||||
(step, mIPack, mBlockSizes, OpExpr<MapF,IndexPack,Exprs>
|
|
||||||
( range()->map(), mIPack, mOutIndex, step, exs ) );
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
template <class MapF, class... Indices>
|
|
||||||
template <class Exprs>
|
|
||||||
auto MapIndex<MapF,Indices...>::iforh(Exprs exs) const
|
|
||||||
-> decltype(RPackNum<sizeof...(Indices)-1>::mkForh(mIPack, exs))
|
|
||||||
{
|
|
||||||
return RPackNum<sizeof...(Indices)-1>::mkForh(mIPack, exs);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/*************************
|
|
||||||
* MapRangeFactory *
|
|
||||||
*************************/
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
MapRangeFactory<MapF,Ranges...>::MapRangeFactory(const MapF& mapf, const std::shared_ptr<Ranges>&... rs)
|
|
||||||
{
|
|
||||||
mProd = std::shared_ptr< MapRange<MapF,Ranges...> >( new MapRange<MapF,Ranges...>( mapf, rs... ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
MapRangeFactory<MapF,Ranges...>::MapRangeFactory(const MapF& mapf, const typename MapRange<MapF,Ranges...>::Space& st)
|
|
||||||
{
|
|
||||||
mProd = std::shared_ptr< MapRange<MapF,Ranges...> >( new MapRange<MapF,Ranges...>( mapf, st ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
std::shared_ptr<RangeBase> MapRangeFactory<MapF,Ranges...>::create()
|
|
||||||
{
|
|
||||||
mProd = checkIfCreated( std::dynamic_pointer_cast<oType>( mProd )->mSpace );
|
|
||||||
setSelf();
|
|
||||||
return mProd;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
std::shared_ptr<RangeBase> MapRangeFactory<MapF,Ranges...>::checkIfCreated(const std::tuple<std::shared_ptr<Ranges>...>& ptp)
|
|
||||||
{
|
|
||||||
std::shared_ptr<RangeBase> out;
|
|
||||||
bool check = false;
|
|
||||||
for(auto& x: MapRangeFactoryProductMap::mAleadyCreated){
|
|
||||||
if(x.second.size() == sizeof...(Ranges)){
|
|
||||||
check = RPackNum<sizeof...(Ranges)-1>::checkIfCreated(ptp, x.second);
|
|
||||||
if(check){
|
|
||||||
out = x.first;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(not check){
|
|
||||||
std::vector<std::intptr_t> pv(sizeof...(Ranges));
|
|
||||||
RPackNum<sizeof...(Ranges)-1>::RangesToVec(ptp, pv);
|
|
||||||
pv.push_back( reinterpret_cast<std::intptr_t>
|
|
||||||
( &std::dynamic_pointer_cast<oType>( mProd )->mMapf ) );
|
|
||||||
MapRangeFactoryProductMap::mAleadyCreated[mProd] = pv;
|
|
||||||
out = mProd;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************
|
|
||||||
* MapRange *
|
|
||||||
******************/
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
void MapRange<MapF,Ranges...>::mkOutRange()
|
|
||||||
{
|
|
||||||
//FunctionalMultiArray<typename MapF::value_type,MapF,Ranges...> fma(mSpace, mMapf);
|
|
||||||
std::map<typename MapF::value_type,size_t> mult;
|
|
||||||
for(auto ii = mMapf.begin(); ii.max() != ii.pos(); ++ii) {
|
|
||||||
mult[mMapf[ii]]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<typename MapF::value_type> outmeta(mult.size());
|
|
||||||
std::vector<size_t> outmult(mult.size());
|
|
||||||
|
|
||||||
size_t cnt = 0;
|
|
||||||
for(auto& x: mult){
|
|
||||||
outmeta[cnt] = x.first;
|
|
||||||
outmult[cnt] = x.second;
|
|
||||||
++cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
ORFType orf(outmeta);
|
|
||||||
mOutRange = std::dynamic_pointer_cast<ORType>( orf.create() );
|
|
||||||
mMapMult = MultiArray<size_t,ORType>( mOutRange, outmult );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
MapRange<MapF,Ranges...>::MapRange(const MapF& mapf, const std::shared_ptr<Ranges>&... rs) :
|
|
||||||
mSpace(std::make_tuple(rs...)),
|
|
||||||
mMapf(mapf)
|
|
||||||
{
|
|
||||||
mkOutRange();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
MapRange<MapF,Ranges...>::MapRange(const MapF& mapf, const Space& space) :
|
|
||||||
mSpace( space ),
|
|
||||||
mMapf(mapf)
|
|
||||||
{
|
|
||||||
mkOutRange();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
template <size_t N>
|
|
||||||
auto MapRange<MapF,Ranges...>::get() const -> decltype( *std::get<N>( mSpace ) )&
|
|
||||||
{
|
|
||||||
return *std::get<N>(mSpace);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
template <size_t N>
|
|
||||||
auto MapRange<MapF,Ranges...>::getPtr() const -> decltype( std::get<N>( mSpace ) )&
|
|
||||||
{
|
|
||||||
return std::get<N>(mSpace);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
auto MapRange<MapF,Ranges...>::outRange() const -> std::shared_ptr<ORType>
|
|
||||||
{
|
|
||||||
return mOutRange;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
const MapF& MapRange<MapF,Ranges...>::map() const
|
|
||||||
{
|
|
||||||
return mMapf;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
size_t MapRange<MapF,Ranges...>::dim() const
|
|
||||||
{
|
|
||||||
return sdim;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
size_t MapRange<MapF,Ranges...>::size() const
|
|
||||||
{
|
|
||||||
return mOutRange->size();
|
|
||||||
//return RPackNum<sizeof...(Ranges)-1>::getSize(mSpace);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
SpaceType MapRange<MapF,Ranges...>::spaceType() const
|
|
||||||
{
|
|
||||||
return SpaceType::ANY;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
const typename MapRange<MapF,Ranges...>::Space& MapRange<MapF,Ranges...>::space() const
|
|
||||||
{
|
|
||||||
return mSpace;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
std::string MapRange<MapF,Ranges...>::stringMeta(size_t pos) const
|
|
||||||
{
|
|
||||||
auto i = begin();
|
|
||||||
i = pos;
|
|
||||||
return "[ " + RPackNum<sizeof...(Ranges)-1>::metaTupleToString(i.meta()) + " ]";
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
std::vector<char> MapRange<MapF,Ranges...>::data() const
|
|
||||||
{
|
|
||||||
DataHeader h;
|
|
||||||
h.spaceType = static_cast<int>( SpaceType::ANY );
|
|
||||||
h.metaSize = sizeof...(Ranges);
|
|
||||||
h.multiple = 1;
|
|
||||||
std::vector<char> out;
|
|
||||||
//out.reserve(h.metaSize + sizeof(DataHeader));
|
|
||||||
char* hcp = reinterpret_cast<char*>(&h);
|
|
||||||
out.insert(out.end(), hcp, hcp + sizeof(DataHeader));
|
|
||||||
RPackNum<sizeof...(Ranges)-1>::fillRangeDataVec(out, mSpace);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
typename MapRange<MapF,Ranges...>::IndexType MapRange<MapF,Ranges...>::begin() const
|
|
||||||
{
|
|
||||||
MapIndex<MapF,typename Ranges::IndexType...>
|
|
||||||
i( std::dynamic_pointer_cast<MapRange<MapF,Ranges...> >
|
|
||||||
( std::shared_ptr<RangeBase>( RB::mThis ) ) );
|
|
||||||
i = 0;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
typename MapRange<MapF,Ranges...>::IndexType MapRange<MapF,Ranges...>::end() const
|
|
||||||
{
|
|
||||||
MapIndex<MapF,typename Ranges::IndexType...>
|
|
||||||
i( std::dynamic_pointer_cast<MapRange<MapF,Ranges...> >
|
|
||||||
( std::shared_ptr<RangeBase>( RB::mThis )) );
|
|
||||||
i = size();
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
auto MapRange<MapF,Ranges...>::mapMultiplicity() const
|
|
||||||
-> const MultiArray<size_t,ORType>&
|
|
||||||
{
|
|
||||||
return mMapMult;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
auto MapRange<MapF,Ranges...>::explMapMultiplicity() const
|
|
||||||
-> MultiArray<size_t,MapRange>
|
|
||||||
{
|
|
||||||
auto tmp = mMapMult;
|
|
||||||
return tmp.format( std::dynamic_pointer_cast<MapRange<MapF,Ranges...> >
|
|
||||||
( std::shared_ptr<RangeBase>( RB::mThis )) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MapF, class... Ranges>
|
|
||||||
template <class... ERanges>
|
|
||||||
auto MapRange<MapF,Ranges...>::cat(const std::shared_ptr<MapRange<ERanges...> >& erange)
|
|
||||||
-> std::shared_ptr<MapRange<Ranges...,ERanges...> >
|
|
||||||
{
|
|
||||||
auto crange = std::tuple_cat(mSpace, erange->space());
|
|
||||||
MapRangeFactory<Ranges...,ERanges...> rf(crange);
|
|
||||||
return std::dynamic_pointer_cast<MapRange<Ranges...,ERanges...> >(rf.create());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
264
src/include/multi_array.cc.h
Normal file
264
src/include/multi_array.cc.h
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
|
||||||
|
#include "multi_array.h"
|
||||||
|
|
||||||
|
namespace MultiArrayTools
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
Scalar<T> scalar(const T& in)
|
||||||
|
{
|
||||||
|
NullRF nrf;
|
||||||
|
return Scalar<T>( std::dynamic_pointer_cast<NullRange>( nrf.create() ), std::vector<T>( { in } ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************
|
||||||
|
* MultiArray *
|
||||||
|
*******************/
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MultiArray<T,SRanges...>::MultiArray(const typename CRange::Space& space) :
|
||||||
|
MutableMultiArrayBase<T,SRanges...>(space),
|
||||||
|
mCont(MAB::mRange->size())
|
||||||
|
{
|
||||||
|
MAB::mInit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MultiArray<T,SRanges...>::MultiArray(const typename CRange::Space& space,
|
||||||
|
std::vector<T>&& vec) :
|
||||||
|
MutableMultiArrayBase<T,SRanges...>(space),
|
||||||
|
mCont(vec)
|
||||||
|
{
|
||||||
|
MAB::mInit = true;
|
||||||
|
if(mCont.size() > MAB::mRange->size()){
|
||||||
|
mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges) :
|
||||||
|
MutableMultiArrayBase<T,SRanges...>(ranges...),
|
||||||
|
mCont(MAB::mRange->size())
|
||||||
|
{
|
||||||
|
MAB::mInit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges, const T& val) :
|
||||||
|
MutableMultiArrayBase<T,SRanges...>(ranges...),
|
||||||
|
mCont(MAB::mRange->size(), val)
|
||||||
|
{
|
||||||
|
MAB::mInit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges, const std::vector<T>& vec) :
|
||||||
|
MutableMultiArrayBase<T,SRanges...>(ranges...),
|
||||||
|
mCont(vec)
|
||||||
|
{
|
||||||
|
MAB::mInit = true;
|
||||||
|
if(mCont.size() > MAB::mRange->size()){
|
||||||
|
mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges, std::vector<T>&& vec) :
|
||||||
|
MutableMultiArrayBase<T,SRanges...>(ranges...),
|
||||||
|
mCont(vec)
|
||||||
|
{
|
||||||
|
MAB::mInit = true;
|
||||||
|
if(mCont.size() > MAB::mRange->size()){
|
||||||
|
mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MultiArray<T,SRanges...>::MultiArray(MultiArray<T,AnonymousRange>&& ama, SIZET<SRanges>... sizes) :
|
||||||
|
MutableMultiArrayBase<T,SRanges...>
|
||||||
|
( ama.range()->template get<0>().template scast<SRanges...>(sizes...)->space() ),
|
||||||
|
mCont( std::move( ama.mCont ) )
|
||||||
|
{
|
||||||
|
MAB::mInit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
template <class Range2, class Range3>
|
||||||
|
MultiArray<T,SRanges...>::MultiArray(const MultiArray<MultiArray<T,Range2>,Range3> in) :
|
||||||
|
MutableMultiArrayBase<T,SRanges...>(merge(in.range(), in[ in.beginIndex() ].range()))
|
||||||
|
// assert that Range2 has always same extension
|
||||||
|
{
|
||||||
|
MAB::mInit = true;
|
||||||
|
mCont.clear();
|
||||||
|
for(auto i = in.beginIndex(); i != in.endIndex(); ++i){
|
||||||
|
mCont.insert(mCont.end(), in[i].mCont.begin(), in[i].mCont.end());
|
||||||
|
}
|
||||||
|
assert(mCont.size() == MAB::mRange->size());
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
template <class Range2, class Range3>
|
||||||
|
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator=(const MultiArray<MultiArray<T,Range2>,Range3> in)
|
||||||
|
{
|
||||||
|
MAB::mRange.reset(new Range(merge(in.range(), in[ in.beginIndex() ].range())));
|
||||||
|
// assert that Range2 has always same extension
|
||||||
|
mCont.clear();
|
||||||
|
for(auto i = in.beginIndex(); i != in.endIndex(); ++i){
|
||||||
|
mCont.insert(mCont.end(), in[i].mCont.begin(), in[i].mCont.end());
|
||||||
|
}
|
||||||
|
assert(mCont.size() == MAB::mRange->size());
|
||||||
|
return *this;
|
||||||
|
} */
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
T& MultiArray<T,SRanges...>::operator[](const IndexType& i)
|
||||||
|
{
|
||||||
|
return mCont[ i.pos() ];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
const T& MultiArray<T,SRanges...>::operator[](const IndexType& i) const
|
||||||
|
{
|
||||||
|
return mCont[ i.pos() ];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
T& MultiArray<T,SRanges...>::at(const typename IndexType::MetaType& meta)
|
||||||
|
{
|
||||||
|
return mCont[ MAB::beginIndex().at(meta).pos() ];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
const T& MultiArray<T,SRanges...>::at(const typename IndexType::MetaType& meta) const
|
||||||
|
{
|
||||||
|
return mCont[ MAB::beginIndex().at(meta).pos() ];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
bool MultiArray<T,SRanges...>::isConst() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
bool MultiArray<T,SRanges...>::isSlice() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
template <class... SRanges2>
|
||||||
|
MultiArray<T,SRanges2...> MultiArray<T,SRanges...>::format(const std::shared_ptr<SRanges2>&... nrs)
|
||||||
|
{
|
||||||
|
return MultiArray<T,SRanges2...>( nrs... , std::move(mCont) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
const T* MultiArray<T,SRanges...>::data() const
|
||||||
|
{
|
||||||
|
return mCont.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
T* MultiArray<T,SRanges...>::data()
|
||||||
|
{
|
||||||
|
return mCont.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > MultiArray<T,SRanges...>::anonymous(bool slice) const
|
||||||
|
{
|
||||||
|
AnonymousRangeFactory arf(MAB::mRange->space());
|
||||||
|
if(slice){
|
||||||
|
return std::make_shared<ConstSlice<T,AnonymousRange> >
|
||||||
|
( std::dynamic_pointer_cast<AnonymousRange>( arf.create() ),
|
||||||
|
data() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return std::make_shared<MultiArray<T,AnonymousRange> >
|
||||||
|
( std::dynamic_pointer_cast<AnonymousRange>( arf.create() ),
|
||||||
|
mCont );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > MultiArray<T,SRanges...>::anonymousMove()
|
||||||
|
{
|
||||||
|
AnonymousRangeFactory arf(MAB::mRange->space());
|
||||||
|
MAB::mInit = false;
|
||||||
|
return std::make_shared<MultiArray<T,AnonymousRange> >
|
||||||
|
( std::dynamic_pointer_cast<AnonymousRange>( arf.create() ),
|
||||||
|
std::move(mCont) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator=(const T& in)
|
||||||
|
{
|
||||||
|
for(auto& x: mCont){
|
||||||
|
x = in;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator+=(const MultiArray& in)
|
||||||
|
{
|
||||||
|
if(not MAB::mInit){ // not initialized by default constructor !!
|
||||||
|
(*this) = in;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert( PackNum<sizeof...(SRanges)-1>::checkIfSameInstance( MAB::mRange->space(), in.mRange->space() ) );
|
||||||
|
std::transform(mCont.begin(), mCont.end(), in.mCont.begin(), mCont.begin(), std::plus<T>());
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator-=(const MultiArray& in)
|
||||||
|
{
|
||||||
|
if(not MAB::mInit){ // not initialized by default constructor !!
|
||||||
|
(*this) = in;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert( PackNum<sizeof...(SRanges)-1>::checkIfSameInstance( MAB::mRange->space(), in.mRange->space() ) );
|
||||||
|
std::transform(mCont.begin(), mCont.end(), in.mCont.begin(), mCont.begin(), std::minus<T>());
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator*=(const T& in)
|
||||||
|
{
|
||||||
|
for(auto& x: mCont){
|
||||||
|
x *= in;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator/=(const T& in)
|
||||||
|
{
|
||||||
|
for(auto& x: mCont){
|
||||||
|
x /= in;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MultiArray<T,SRanges...>::operator T() const
|
||||||
|
{
|
||||||
|
static_assert( sizeof...(SRanges) == 1, "try to cast non-scalar type into scalar" );
|
||||||
|
// TODO: check that SIZE is statically = 1 !!!
|
||||||
|
return mCont[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
auto MultiArray<T,SRanges...>::cat() const
|
||||||
|
-> decltype(ArrayCatter<T>::cat(*this))
|
||||||
|
{
|
||||||
|
return ArrayCatter<T>::cat(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -131,265 +131,5 @@ namespace MultiArrayTools
|
||||||
* --- TEMPLATE CODE --- *
|
* --- TEMPLATE CODE --- *
|
||||||
* ========================= */
|
* ========================= */
|
||||||
|
|
||||||
namespace MultiArrayTools
|
|
||||||
{
|
|
||||||
template <typename T>
|
|
||||||
Scalar<T> scalar(const T& in)
|
|
||||||
{
|
|
||||||
NullRF nrf;
|
|
||||||
return Scalar<T>( std::dynamic_pointer_cast<NullRange>( nrf.create() ), std::vector<T>( { in } ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************
|
|
||||||
* MultiArray *
|
|
||||||
*******************/
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MultiArray<T,SRanges...>::MultiArray(const typename CRange::Space& space) :
|
|
||||||
MutableMultiArrayBase<T,SRanges...>(space),
|
|
||||||
mCont(MAB::mRange->size())
|
|
||||||
{
|
|
||||||
MAB::mInit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MultiArray<T,SRanges...>::MultiArray(const typename CRange::Space& space,
|
|
||||||
std::vector<T>&& vec) :
|
|
||||||
MutableMultiArrayBase<T,SRanges...>(space),
|
|
||||||
mCont(vec)
|
|
||||||
{
|
|
||||||
MAB::mInit = true;
|
|
||||||
if(mCont.size() > MAB::mRange->size()){
|
|
||||||
mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges) :
|
|
||||||
MutableMultiArrayBase<T,SRanges...>(ranges...),
|
|
||||||
mCont(MAB::mRange->size())
|
|
||||||
{
|
|
||||||
MAB::mInit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges, const T& val) :
|
|
||||||
MutableMultiArrayBase<T,SRanges...>(ranges...),
|
|
||||||
mCont(MAB::mRange->size(), val)
|
|
||||||
{
|
|
||||||
MAB::mInit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges, const std::vector<T>& vec) :
|
|
||||||
MutableMultiArrayBase<T,SRanges...>(ranges...),
|
|
||||||
mCont(vec)
|
|
||||||
{
|
|
||||||
MAB::mInit = true;
|
|
||||||
if(mCont.size() > MAB::mRange->size()){
|
|
||||||
mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges, std::vector<T>&& vec) :
|
|
||||||
MutableMultiArrayBase<T,SRanges...>(ranges...),
|
|
||||||
mCont(vec)
|
|
||||||
{
|
|
||||||
MAB::mInit = true;
|
|
||||||
if(mCont.size() > MAB::mRange->size()){
|
|
||||||
mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MultiArray<T,SRanges...>::MultiArray(MultiArray<T,AnonymousRange>&& ama, SIZET<SRanges>... sizes) :
|
|
||||||
MutableMultiArrayBase<T,SRanges...>
|
|
||||||
( ama.range()->template get<0>().template scast<SRanges...>(sizes...)->space() ),
|
|
||||||
mCont( std::move( ama.mCont ) )
|
|
||||||
{
|
|
||||||
MAB::mInit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
template <class Range2, class Range3>
|
|
||||||
MultiArray<T,SRanges...>::MultiArray(const MultiArray<MultiArray<T,Range2>,Range3> in) :
|
|
||||||
MutableMultiArrayBase<T,SRanges...>(merge(in.range(), in[ in.beginIndex() ].range()))
|
|
||||||
// assert that Range2 has always same extension
|
|
||||||
{
|
|
||||||
MAB::mInit = true;
|
|
||||||
mCont.clear();
|
|
||||||
for(auto i = in.beginIndex(); i != in.endIndex(); ++i){
|
|
||||||
mCont.insert(mCont.end(), in[i].mCont.begin(), in[i].mCont.end());
|
|
||||||
}
|
|
||||||
assert(mCont.size() == MAB::mRange->size());
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
template <class Range2, class Range3>
|
|
||||||
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator=(const MultiArray<MultiArray<T,Range2>,Range3> in)
|
|
||||||
{
|
|
||||||
MAB::mRange.reset(new Range(merge(in.range(), in[ in.beginIndex() ].range())));
|
|
||||||
// assert that Range2 has always same extension
|
|
||||||
mCont.clear();
|
|
||||||
for(auto i = in.beginIndex(); i != in.endIndex(); ++i){
|
|
||||||
mCont.insert(mCont.end(), in[i].mCont.begin(), in[i].mCont.end());
|
|
||||||
}
|
|
||||||
assert(mCont.size() == MAB::mRange->size());
|
|
||||||
return *this;
|
|
||||||
} */
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
T& MultiArray<T,SRanges...>::operator[](const IndexType& i)
|
|
||||||
{
|
|
||||||
return mCont[ i.pos() ];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
const T& MultiArray<T,SRanges...>::operator[](const IndexType& i) const
|
|
||||||
{
|
|
||||||
return mCont[ i.pos() ];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
T& MultiArray<T,SRanges...>::at(const typename IndexType::MetaType& meta)
|
|
||||||
{
|
|
||||||
return mCont[ MAB::beginIndex().at(meta).pos() ];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
const T& MultiArray<T,SRanges...>::at(const typename IndexType::MetaType& meta) const
|
|
||||||
{
|
|
||||||
return mCont[ MAB::beginIndex().at(meta).pos() ];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
bool MultiArray<T,SRanges...>::isConst() const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
bool MultiArray<T,SRanges...>::isSlice() const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
template <class... SRanges2>
|
|
||||||
MultiArray<T,SRanges2...> MultiArray<T,SRanges...>::format(const std::shared_ptr<SRanges2>&... nrs)
|
|
||||||
{
|
|
||||||
return MultiArray<T,SRanges2...>( nrs... , std::move(mCont) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
const T* MultiArray<T,SRanges...>::data() const
|
|
||||||
{
|
|
||||||
return mCont.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
T* MultiArray<T,SRanges...>::data()
|
|
||||||
{
|
|
||||||
return mCont.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > MultiArray<T,SRanges...>::anonymous(bool slice) const
|
|
||||||
{
|
|
||||||
AnonymousRangeFactory arf(MAB::mRange->space());
|
|
||||||
if(slice){
|
|
||||||
return std::make_shared<ConstSlice<T,AnonymousRange> >
|
|
||||||
( std::dynamic_pointer_cast<AnonymousRange>( arf.create() ),
|
|
||||||
data() );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return std::make_shared<MultiArray<T,AnonymousRange> >
|
|
||||||
( std::dynamic_pointer_cast<AnonymousRange>( arf.create() ),
|
|
||||||
mCont );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > MultiArray<T,SRanges...>::anonymousMove()
|
|
||||||
{
|
|
||||||
AnonymousRangeFactory arf(MAB::mRange->space());
|
|
||||||
MAB::mInit = false;
|
|
||||||
return std::make_shared<MultiArray<T,AnonymousRange> >
|
|
||||||
( std::dynamic_pointer_cast<AnonymousRange>( arf.create() ),
|
|
||||||
std::move(mCont) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator=(const T& in)
|
|
||||||
{
|
|
||||||
for(auto& x: mCont){
|
|
||||||
x = in;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator+=(const MultiArray& in)
|
|
||||||
{
|
|
||||||
if(not MAB::mInit){ // not initialized by default constructor !!
|
|
||||||
(*this) = in;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert( PackNum<sizeof...(SRanges)-1>::checkIfSameInstance( MAB::mRange->space(), in.mRange->space() ) );
|
|
||||||
std::transform(mCont.begin(), mCont.end(), in.mCont.begin(), mCont.begin(), std::plus<T>());
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator-=(const MultiArray& in)
|
|
||||||
{
|
|
||||||
if(not MAB::mInit){ // not initialized by default constructor !!
|
|
||||||
(*this) = in;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert( PackNum<sizeof...(SRanges)-1>::checkIfSameInstance( MAB::mRange->space(), in.mRange->space() ) );
|
|
||||||
std::transform(mCont.begin(), mCont.end(), in.mCont.begin(), mCont.begin(), std::minus<T>());
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator*=(const T& in)
|
|
||||||
{
|
|
||||||
for(auto& x: mCont){
|
|
||||||
x *= in;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator/=(const T& in)
|
|
||||||
{
|
|
||||||
for(auto& x: mCont){
|
|
||||||
x /= in;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MultiArray<T,SRanges...>::operator T() const
|
|
||||||
{
|
|
||||||
static_assert( sizeof...(SRanges) == 1, "try to cast non-scalar type into scalar" );
|
|
||||||
// TODO: check that SIZE is statically = 1 !!!
|
|
||||||
return mCont[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
auto MultiArray<T,SRanges...>::cat() const
|
|
||||||
-> decltype(ArrayCatter<T>::cat(*this))
|
|
||||||
{
|
|
||||||
return ArrayCatter<T>::cat(*this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
223
src/include/multi_array_base.cc.h
Normal file
223
src/include/multi_array_base.cc.h
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
|
||||||
|
#include "multi_array_base.h"
|
||||||
|
|
||||||
|
namespace MultiArrayTools
|
||||||
|
{
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MultiArrayBase *
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MultiArrayBase<T,SRanges...>::MultiArrayBase(const std::shared_ptr<SRanges>&... ranges)
|
||||||
|
{
|
||||||
|
ContainerRangeFactory<T,SRanges...> crf(ranges...);
|
||||||
|
mRange = std::dynamic_pointer_cast<ContainerRange<T,SRanges...> >( crf.create() );
|
||||||
|
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MultiArrayBase<T,SRanges...>::MultiArrayBase(const typename CRange::Space& space)
|
||||||
|
{
|
||||||
|
ContainerRangeFactory<T,SRanges...> crf(space);
|
||||||
|
mRange = std::dynamic_pointer_cast<ContainerRange<T,SRanges...> >( crf.create() );
|
||||||
|
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
template <typename X>
|
||||||
|
const T& MultiArrayBase<T,SRanges...>::operator[](const ContainerIndex<X,typename SRanges::IndexType...>& i)
|
||||||
|
{
|
||||||
|
IndexType ii(*mProtoI);
|
||||||
|
ii = i;
|
||||||
|
return (*this)[ii];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
size_t MultiArrayBase<T,SRanges...>::size() const
|
||||||
|
{
|
||||||
|
return mRange->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
typename MultiArrayBase<T,SRanges...>::IndexType MultiArrayBase<T,SRanges...>::begin() const
|
||||||
|
{
|
||||||
|
IndexType i(*mProtoI);
|
||||||
|
i = 0;
|
||||||
|
return i.setData(data());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
typename MultiArrayBase<T,SRanges...>::IndexType MultiArrayBase<T,SRanges...>::end() const
|
||||||
|
{
|
||||||
|
IndexType i(*mProtoI);
|
||||||
|
i = i.max();
|
||||||
|
//i = mRange->size();
|
||||||
|
return i.setData(data());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
typename MultiArrayBase<T,SRanges...>::IndexType
|
||||||
|
MultiArrayBase<T,SRanges...>::beginIndex() const
|
||||||
|
{
|
||||||
|
IndexType i(*mProtoI);
|
||||||
|
i = 0;
|
||||||
|
return i.setData(data());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
typename MultiArrayBase<T,SRanges...>::IndexType
|
||||||
|
MultiArrayBase<T,SRanges...>::endIndex() const
|
||||||
|
{
|
||||||
|
IndexType i(*mProtoI);
|
||||||
|
i = i.max();
|
||||||
|
//i = mRange->size();
|
||||||
|
return i.setData(data());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
const std::shared_ptr<typename MultiArrayBase<T,SRanges...>::CRange>&
|
||||||
|
MultiArrayBase<T,SRanges...>::range() const
|
||||||
|
{
|
||||||
|
return mRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
bool MultiArrayBase<T,SRanges...>::isConst() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
ConstOperationRoot<T,SRanges...>
|
||||||
|
MultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
||||||
|
{
|
||||||
|
return ConstOperationRoot<T,SRanges...>(*this, inds...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
ConstOperationRoot<T,SRanges...>
|
||||||
|
MultiArrayBase<T,SRanges...>::op(const std::shared_ptr<IndexType>& ind) const
|
||||||
|
{
|
||||||
|
return ConstOperationRoot<T,SRanges...>(data(), *ind);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
template <class... MappedRanges>
|
||||||
|
ConstOperationRoot<T,MappedRanges...>
|
||||||
|
MultiArrayBase<T,SRanges...>::m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const
|
||||||
|
{
|
||||||
|
static_assert(sizeof...(SRanges) == sizeof...(MappedRanges),
|
||||||
|
"number of mapped ranges must be equal to number of original ranges");
|
||||||
|
return ConstOperationRoot<T,MappedRanges...>(*this, inds...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
bool MultiArrayBase<T,SRanges...>::isInit() const
|
||||||
|
{
|
||||||
|
return mInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
template <size_t N>
|
||||||
|
auto MultiArrayBase<T,SRanges...>::getRangePtr() const
|
||||||
|
-> decltype(mRange->template getPtr<N>())
|
||||||
|
{
|
||||||
|
return mRange->template getPtr<N>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************
|
||||||
|
* MutableMultiArrayBase *
|
||||||
|
******************************/
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MutableMultiArrayBase<T,SRanges...>::MutableMultiArrayBase(const std::shared_ptr<SRanges>&... ranges) :
|
||||||
|
MultiArrayBase<T,SRanges...>(ranges...) {}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
MutableMultiArrayBase<T,SRanges...>::MutableMultiArrayBase(const typename CRange::Space& space) :
|
||||||
|
MultiArrayBase<T,SRanges...>(space) {}
|
||||||
|
/*
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
typename MutableMultiArrayBase<T,SRanges...>::IndexType MutableMultiArrayBase<T,SRanges...>::begin()
|
||||||
|
{
|
||||||
|
auto i = mRange->begin();
|
||||||
|
return i.setData(data());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
typename MutableMultiArrayBase<T,SRanges...>::IndexType MutableMultiArrayBase<T,SRanges...>::end()
|
||||||
|
{
|
||||||
|
auto i = mRange->end();
|
||||||
|
return i.setData(data());
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
template <typename X>
|
||||||
|
T& MutableMultiArrayBase<T,SRanges...>::operator[](const ContainerIndex<X,typename SRanges::IndexType...>& i)
|
||||||
|
{
|
||||||
|
IndexType ii(*MAB::mProtoI);
|
||||||
|
ii = i;
|
||||||
|
return (*this)[ii];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
bool MutableMultiArrayBase<T,SRanges...>::isConst() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
OperationRoot<T,SRanges...>
|
||||||
|
MutableMultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds)
|
||||||
|
{
|
||||||
|
return OperationRoot<T,SRanges...>(*this, inds...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
OperationRoot<T,SRanges...>
|
||||||
|
MutableMultiArrayBase<T,SRanges...>::op(const std::shared_ptr<IndexType>& ind)
|
||||||
|
{
|
||||||
|
return OperationRoot<T,SRanges...>(data(), *ind);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
ConstOperationRoot<T,SRanges...>
|
||||||
|
MutableMultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
||||||
|
{
|
||||||
|
return ConstOperationRoot<T,SRanges...>(*this, inds...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
ConstOperationRoot<T,SRanges...>
|
||||||
|
MutableMultiArrayBase<T,SRanges...>::op(const std::shared_ptr<IndexType>& ind) const
|
||||||
|
{
|
||||||
|
return ConstOperationRoot<T,SRanges...>(data(), *ind);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
template <class... MappedRanges>
|
||||||
|
OperationRoot<T,MappedRanges...>
|
||||||
|
MutableMultiArrayBase<T,SRanges...>::m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds)
|
||||||
|
{
|
||||||
|
static_assert(sizeof...(SRanges) == sizeof...(MappedRanges),
|
||||||
|
"number of mapped ranges must be equal to number of original ranges");
|
||||||
|
return OperationRoot<T,MappedRanges...>(*this, inds...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
template <class... MappedRanges>
|
||||||
|
ConstOperationRoot<T,MappedRanges...>
|
||||||
|
MutableMultiArrayBase<T,SRanges...>::m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const
|
||||||
|
{
|
||||||
|
static_assert(sizeof...(SRanges) == sizeof...(MappedRanges),
|
||||||
|
"number of mapped ranges must be equal to number of original ranges");
|
||||||
|
return ConstOperationRoot<T,MappedRanges...>(*this, inds...);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace MultiArrayTools
|
||||||
|
|
|
@ -142,224 +142,5 @@ namespace MultiArrayTools
|
||||||
* --- TEMPLATE CODE --- *
|
* --- TEMPLATE CODE --- *
|
||||||
* ========================= */
|
* ========================= */
|
||||||
|
|
||||||
namespace MultiArrayTools
|
|
||||||
{
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MultiArrayBase *
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MultiArrayBase<T,SRanges...>::MultiArrayBase(const std::shared_ptr<SRanges>&... ranges)
|
|
||||||
{
|
|
||||||
ContainerRangeFactory<T,SRanges...> crf(ranges...);
|
|
||||||
mRange = std::dynamic_pointer_cast<ContainerRange<T,SRanges...> >( crf.create() );
|
|
||||||
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MultiArrayBase<T,SRanges...>::MultiArrayBase(const typename CRange::Space& space)
|
|
||||||
{
|
|
||||||
ContainerRangeFactory<T,SRanges...> crf(space);
|
|
||||||
mRange = std::dynamic_pointer_cast<ContainerRange<T,SRanges...> >( crf.create() );
|
|
||||||
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
template <typename X>
|
|
||||||
const T& MultiArrayBase<T,SRanges...>::operator[](const ContainerIndex<X,typename SRanges::IndexType...>& i)
|
|
||||||
{
|
|
||||||
IndexType ii(*mProtoI);
|
|
||||||
ii = i;
|
|
||||||
return (*this)[ii];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
size_t MultiArrayBase<T,SRanges...>::size() const
|
|
||||||
{
|
|
||||||
return mRange->size();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
typename MultiArrayBase<T,SRanges...>::IndexType MultiArrayBase<T,SRanges...>::begin() const
|
|
||||||
{
|
|
||||||
IndexType i(*mProtoI);
|
|
||||||
i = 0;
|
|
||||||
return i.setData(data());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
typename MultiArrayBase<T,SRanges...>::IndexType MultiArrayBase<T,SRanges...>::end() const
|
|
||||||
{
|
|
||||||
IndexType i(*mProtoI);
|
|
||||||
i = i.max();
|
|
||||||
//i = mRange->size();
|
|
||||||
return i.setData(data());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
typename MultiArrayBase<T,SRanges...>::IndexType
|
|
||||||
MultiArrayBase<T,SRanges...>::beginIndex() const
|
|
||||||
{
|
|
||||||
IndexType i(*mProtoI);
|
|
||||||
i = 0;
|
|
||||||
return i.setData(data());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
typename MultiArrayBase<T,SRanges...>::IndexType
|
|
||||||
MultiArrayBase<T,SRanges...>::endIndex() const
|
|
||||||
{
|
|
||||||
IndexType i(*mProtoI);
|
|
||||||
i = i.max();
|
|
||||||
//i = mRange->size();
|
|
||||||
return i.setData(data());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
const std::shared_ptr<typename MultiArrayBase<T,SRanges...>::CRange>&
|
|
||||||
MultiArrayBase<T,SRanges...>::range() const
|
|
||||||
{
|
|
||||||
return mRange;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
bool MultiArrayBase<T,SRanges...>::isConst() const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
ConstOperationRoot<T,SRanges...>
|
|
||||||
MultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
|
||||||
{
|
|
||||||
return ConstOperationRoot<T,SRanges...>(*this, inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
ConstOperationRoot<T,SRanges...>
|
|
||||||
MultiArrayBase<T,SRanges...>::op(const std::shared_ptr<IndexType>& ind) const
|
|
||||||
{
|
|
||||||
return ConstOperationRoot<T,SRanges...>(data(), *ind);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
template <class... MappedRanges>
|
|
||||||
ConstOperationRoot<T,MappedRanges...>
|
|
||||||
MultiArrayBase<T,SRanges...>::m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const
|
|
||||||
{
|
|
||||||
static_assert(sizeof...(SRanges) == sizeof...(MappedRanges),
|
|
||||||
"number of mapped ranges must be equal to number of original ranges");
|
|
||||||
return ConstOperationRoot<T,MappedRanges...>(*this, inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
bool MultiArrayBase<T,SRanges...>::isInit() const
|
|
||||||
{
|
|
||||||
return mInit;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
template <size_t N>
|
|
||||||
auto MultiArrayBase<T,SRanges...>::getRangePtr() const
|
|
||||||
-> decltype(mRange->template getPtr<N>())
|
|
||||||
{
|
|
||||||
return mRange->template getPtr<N>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************
|
|
||||||
* MutableMultiArrayBase *
|
|
||||||
******************************/
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MutableMultiArrayBase<T,SRanges...>::MutableMultiArrayBase(const std::shared_ptr<SRanges>&... ranges) :
|
|
||||||
MultiArrayBase<T,SRanges...>(ranges...) {}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
MutableMultiArrayBase<T,SRanges...>::MutableMultiArrayBase(const typename CRange::Space& space) :
|
|
||||||
MultiArrayBase<T,SRanges...>(space) {}
|
|
||||||
/*
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
typename MutableMultiArrayBase<T,SRanges...>::IndexType MutableMultiArrayBase<T,SRanges...>::begin()
|
|
||||||
{
|
|
||||||
auto i = mRange->begin();
|
|
||||||
return i.setData(data());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
typename MutableMultiArrayBase<T,SRanges...>::IndexType MutableMultiArrayBase<T,SRanges...>::end()
|
|
||||||
{
|
|
||||||
auto i = mRange->end();
|
|
||||||
return i.setData(data());
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
template <typename X>
|
|
||||||
T& MutableMultiArrayBase<T,SRanges...>::operator[](const ContainerIndex<X,typename SRanges::IndexType...>& i)
|
|
||||||
{
|
|
||||||
IndexType ii(*MAB::mProtoI);
|
|
||||||
ii = i;
|
|
||||||
return (*this)[ii];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
bool MutableMultiArrayBase<T,SRanges...>::isConst() const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
OperationRoot<T,SRanges...>
|
|
||||||
MutableMultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds)
|
|
||||||
{
|
|
||||||
return OperationRoot<T,SRanges...>(*this, inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
OperationRoot<T,SRanges...>
|
|
||||||
MutableMultiArrayBase<T,SRanges...>::op(const std::shared_ptr<IndexType>& ind)
|
|
||||||
{
|
|
||||||
return OperationRoot<T,SRanges...>(data(), *ind);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
ConstOperationRoot<T,SRanges...>
|
|
||||||
MutableMultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
|
||||||
{
|
|
||||||
return ConstOperationRoot<T,SRanges...>(*this, inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
ConstOperationRoot<T,SRanges...>
|
|
||||||
MutableMultiArrayBase<T,SRanges...>::op(const std::shared_ptr<IndexType>& ind) const
|
|
||||||
{
|
|
||||||
return ConstOperationRoot<T,SRanges...>(data(), *ind);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
template <class... MappedRanges>
|
|
||||||
OperationRoot<T,MappedRanges...>
|
|
||||||
MutableMultiArrayBase<T,SRanges...>::m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds)
|
|
||||||
{
|
|
||||||
static_assert(sizeof...(SRanges) == sizeof...(MappedRanges),
|
|
||||||
"number of mapped ranges must be equal to number of original ranges");
|
|
||||||
return OperationRoot<T,MappedRanges...>(*this, inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
template <class... MappedRanges>
|
|
||||||
ConstOperationRoot<T,MappedRanges...>
|
|
||||||
MutableMultiArrayBase<T,SRanges...>::m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const
|
|
||||||
{
|
|
||||||
static_assert(sizeof...(SRanges) == sizeof...(MappedRanges),
|
|
||||||
"number of mapped ranges must be equal to number of original ranges");
|
|
||||||
return ConstOperationRoot<T,MappedRanges...>(*this, inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace MultiArrayTools
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
10
src/include/multi_array_header.cc.h
Normal file
10
src/include/multi_array_header.cc.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
#include "multi_array_operation.cc.h"
|
||||||
|
#include "functional_multi_array.cc.h"
|
||||||
|
#include "helper_tools.cc.h"
|
||||||
|
#include "map_range.cc.h"
|
||||||
|
#include "multi_array_base.cc.h"
|
||||||
|
#include "multi_array.cc.h"
|
||||||
|
#include "slice.cc.h"
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "helper_tools.h"
|
#include "helper_tools.h"
|
||||||
#include "operation_def.h"
|
#include "operation_def.h"
|
||||||
#include "map_range.h"
|
#include "map_range.h"
|
||||||
|
#include "expressions.h"
|
||||||
//#include "slice.h"
|
//#include "slice.h"
|
||||||
//#include "manipulator.h"
|
//#include "manipulator.h"
|
||||||
//#include "range_transformer.h"
|
//#include "range_transformer.h"
|
||||||
|
@ -61,4 +62,6 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "multi_array_header.cc.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
548
src/include/multi_array_operation.cc.h
Normal file
548
src/include/multi_array_operation.cc.h
Normal file
|
@ -0,0 +1,548 @@
|
||||||
|
|
||||||
|
#include "multi_array_operation.h"
|
||||||
|
|
||||||
|
/* ========================= *
|
||||||
|
* --- TEMPLATE CODE --- *
|
||||||
|
* ========================= */
|
||||||
|
|
||||||
|
namespace MultiArrayTools
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
using namespace MultiArrayHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************
|
||||||
|
* OperationTemplate *
|
||||||
|
***************************/
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T, class OperationClass>
|
||||||
|
template <class Second>
|
||||||
|
auto OperationBase<T,OperationClass>::operator+(const OperationBase<T,Second>& in) const
|
||||||
|
-> Operation<T,plus<T>,OperationClass,Second>
|
||||||
|
{
|
||||||
|
return Operation<T,plus<T>,OperationClass,Second>(THIS(), in.THIS());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OperationClass>
|
||||||
|
template <class Second>
|
||||||
|
auto OperationBase<T,OperationClass>::operator-(const OperationBase<T,Second>& in) const
|
||||||
|
-> Operation<T,minus<T>,OperationClass,Second>
|
||||||
|
{
|
||||||
|
return Operation<T,minus<T>,OperationClass,Second>(THIS(), in.THIS());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OperationClass>
|
||||||
|
template <class Second>
|
||||||
|
auto OperationBase<T,OperationClass>::operator*(const OperationBase<T,Second>& in) const
|
||||||
|
-> Operation<T,multiplies<T>,OperationClass,Second>
|
||||||
|
{
|
||||||
|
return Operation<T,multiplies<T>,OperationClass,Second>(THIS(), in.THIS());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OperationClass>
|
||||||
|
template <class Second>
|
||||||
|
auto OperationBase<T,OperationClass>::operator/(const OperationBase<T,Second>& in) const
|
||||||
|
-> Operation<T,divides<T>,OperationClass,Second>
|
||||||
|
{
|
||||||
|
return Operation<T,divides<T>,OperationClass,Second>(THIS(), in.THIS());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OperationClass>
|
||||||
|
template <class IndexType>
|
||||||
|
auto OperationBase<T,OperationClass>::c(const std::shared_ptr<IndexType>& ind) const
|
||||||
|
-> Contraction<T,OperationClass,IndexType>
|
||||||
|
{
|
||||||
|
return Contraction<T,OperationClass,IndexType>(THIS(), ind);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OperationClass>
|
||||||
|
template <class... Indices>
|
||||||
|
auto OperationBase<T,OperationClass>::sl(const std::shared_ptr<Indices>&... inds) const
|
||||||
|
-> ConstSlice<T,typename Indices::RangeType...>
|
||||||
|
{
|
||||||
|
ConstSlice<T,typename Indices::RangeType...> out(inds->range()...);
|
||||||
|
out.define(inds...) = THIS();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OperationClass>
|
||||||
|
template <class... Indices>
|
||||||
|
auto OperationBase<T,OperationClass>::slc(const std::shared_ptr<Indices>&... inds) const
|
||||||
|
-> SliceContraction<T,OperationClass,Indices...>
|
||||||
|
{
|
||||||
|
return SliceContraction<T,OperationClass,Indices...>
|
||||||
|
(THIS(), inds...);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************
|
||||||
|
* OperationMaster::AssignmentExpr *
|
||||||
|
*****************************************/
|
||||||
|
|
||||||
|
template <typename T, class OpClass, class... Ranges>
|
||||||
|
OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::
|
||||||
|
AssignmentExpr(OperationMaster& m, const OpClass& sec) :
|
||||||
|
mM(m), mSec(sec) {}
|
||||||
|
|
||||||
|
template <typename T, class OpClass, class... Ranges>
|
||||||
|
inline void OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::
|
||||||
|
operator()(size_t start, ExtType last) const
|
||||||
|
{
|
||||||
|
//VCHECK(mSec.template get<ExtType>(last));
|
||||||
|
mM.add(start, mSec.template get<ExtType>(last) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OpClass, class... Ranges>
|
||||||
|
typename OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::ExtType
|
||||||
|
OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::
|
||||||
|
rootSteps(std::intptr_t iPtrNum) const
|
||||||
|
{
|
||||||
|
return mSec.rootSteps(iPtrNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************
|
||||||
|
* OperationMaster *
|
||||||
|
*************************/
|
||||||
|
|
||||||
|
template <typename T, class OpClass, class... Ranges>
|
||||||
|
OperationMaster<T,OpClass,Ranges...>::
|
||||||
|
OperationMaster(MutableMultiArrayBase<T,Ranges...>& ma, const OpClass& second,
|
||||||
|
IndexType& index) :
|
||||||
|
mSecond(second), mDataPtr(ma.data()),
|
||||||
|
mIndex(index)
|
||||||
|
{
|
||||||
|
performAssignment(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OpClass, class... Ranges>
|
||||||
|
OperationMaster<T,OpClass,Ranges...>::
|
||||||
|
OperationMaster(T* data, const OpClass& second,
|
||||||
|
IndexType& index) :
|
||||||
|
mSecond(second), mDataPtr(data),
|
||||||
|
mIndex(index)
|
||||||
|
{
|
||||||
|
performAssignment(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OpClass, class... Ranges>
|
||||||
|
void OperationMaster<T,OpClass,Ranges...>::performAssignment(std::intptr_t blockIndexNum)
|
||||||
|
{
|
||||||
|
AssignmentExpr ae(*this, mSecond); // Expression to be executed within loop
|
||||||
|
const auto loop = mSecond.template loop<decltype(mIndex.ifor(1,ae))>( mIndex.ifor(1,ae) );
|
||||||
|
// hidden Loops outside ! -> auto vectorizable
|
||||||
|
loop(); // execute overall loop(s) and so internal hidden loops and so the inherited expressions
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OpClass, class... Ranges>
|
||||||
|
inline T OperationMaster<T,OpClass,Ranges...>::get(size_t pos) const
|
||||||
|
{
|
||||||
|
return mDataPtr[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************
|
||||||
|
* ConstOperationRoot *
|
||||||
|
****************************/
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
ConstOperationRoot<T,Ranges...>::
|
||||||
|
ConstOperationRoot(const MultiArrayBase<T,Ranges...>& ma,
|
||||||
|
const std::shared_ptr<typename Ranges::IndexType>&... indices) :
|
||||||
|
mDataPtr(ma.data()),
|
||||||
|
mIndex( ma.begin() )
|
||||||
|
{
|
||||||
|
//VCHECK(ma.data());
|
||||||
|
mIndex(indices...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
ConstOperationRoot<T,Ranges...>::
|
||||||
|
ConstOperationRoot(std::shared_ptr<MultiArrayBase<T,Ranges...> > maptr,
|
||||||
|
const std::shared_ptr<typename Ranges::IndexType>&... indices) :
|
||||||
|
mDataPtr(maptr->data()),
|
||||||
|
mIndex(maptr->begin()),
|
||||||
|
mMaPtr(maptr)
|
||||||
|
{
|
||||||
|
mIndex(indices...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
ConstOperationRoot<T,Ranges...>::
|
||||||
|
ConstOperationRoot(const T* data, const IndexType& ind) :
|
||||||
|
mDataPtr(data),
|
||||||
|
mIndex( ind ) { }
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
template <class ET>
|
||||||
|
inline T ConstOperationRoot<T,Ranges...>::get(ET pos) const
|
||||||
|
{
|
||||||
|
return mDataPtr[pos.val()+mOff];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
template <class ET>
|
||||||
|
inline const ConstOperationRoot<T,Ranges...>& ConstOperationRoot<T,Ranges...>::set(ET pos) const
|
||||||
|
{
|
||||||
|
mIndex = pos.val();
|
||||||
|
mOff = mIndex.pos();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
const T* ConstOperationRoot<T,Ranges...>::data() const
|
||||||
|
{
|
||||||
|
return mDataPtr + mIndex().pos();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
MExt<void> ConstOperationRoot<T,Ranges...>::rootSteps(std::intptr_t iPtrNum) const
|
||||||
|
{
|
||||||
|
return MExt<void>(getStepSize( mIndex, iPtrNum ));
|
||||||
|
//return MExt<void>(getStepSize( getRootIndices( mIndex->info() ), iPtrNum ));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
template <class Expr>
|
||||||
|
Expr ConstOperationRoot<T,Ranges...>::loop(Expr exp) const
|
||||||
|
{
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************
|
||||||
|
* StaticCast *
|
||||||
|
********************/
|
||||||
|
|
||||||
|
template <typename T, class Op>
|
||||||
|
StaticCast<T,Op>::StaticCast(const Op& op) : mOp(op) {}
|
||||||
|
|
||||||
|
template <typename T, class Op>
|
||||||
|
template <class ET>
|
||||||
|
inline T StaticCast<T,Op>::get(ET pos) const
|
||||||
|
{
|
||||||
|
return static_cast<T>( mOp.get(pos) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Op>
|
||||||
|
template <class ET>
|
||||||
|
inline const StaticCast<T,Op>& StaticCast<T,Op>::set(ET pos) const
|
||||||
|
{
|
||||||
|
mOp.set(pos);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Op>
|
||||||
|
auto StaticCast<T,Op>::rootSteps(std::intptr_t iPtrNum) const
|
||||||
|
-> decltype(mOp.rootSteps(iPtrNum))
|
||||||
|
{
|
||||||
|
return mOp.rootSteps(iPtrNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Op>
|
||||||
|
template <class Expr>
|
||||||
|
Expr StaticCast<T,Op>::loop(Expr exp) const
|
||||||
|
{
|
||||||
|
return mOp.loop(exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************
|
||||||
|
* MetaOperationRoot *
|
||||||
|
****************************/
|
||||||
|
|
||||||
|
template <class... Ranges>
|
||||||
|
MetaOperationRoot<Ranges...>::
|
||||||
|
MetaOperationRoot(const IndexType& ind) :
|
||||||
|
mIndex( ind ) { }
|
||||||
|
|
||||||
|
template <class... Ranges>
|
||||||
|
template <class ET>
|
||||||
|
inline typename MetaOperationRoot<Ranges...>::value_type
|
||||||
|
MetaOperationRoot<Ranges...>::get(ET pos) const
|
||||||
|
{
|
||||||
|
//VCHECK(pos.val());
|
||||||
|
//VCHECK(mDataPtr);
|
||||||
|
//VCHECK(mDataPtr[pos.val()])
|
||||||
|
return mIndex.meta(pos.val());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Ranges>
|
||||||
|
template <class ET>
|
||||||
|
inline const MetaOperationRoot<Ranges...>& MetaOperationRoot<Ranges...>::set(ET pos) const
|
||||||
|
{
|
||||||
|
mIndex = pos.val();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Ranges>
|
||||||
|
MExt<void> MetaOperationRoot<Ranges...>::rootSteps(std::intptr_t iPtrNum) const
|
||||||
|
{
|
||||||
|
return MExt<void>(getStepSize( mIndex, iPtrNum ));
|
||||||
|
//return MExt<void>(getStepSize( getRootIndices( mIndex->info() ), iPtrNum ));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class... Ranges>
|
||||||
|
template <class Expr>
|
||||||
|
Expr MetaOperationRoot<Ranges...>::loop(Expr exp) const
|
||||||
|
{
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************
|
||||||
|
* OperationRoot *
|
||||||
|
***********************/
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
OperationRoot<T,Ranges...>::
|
||||||
|
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
||||||
|
const std::shared_ptr<typename Ranges::IndexType>&... indices) :
|
||||||
|
mDataPtr(ma.data()),
|
||||||
|
mIndex( ma.begin() )
|
||||||
|
{
|
||||||
|
mIndex(indices...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
OperationRoot<T,Ranges...>::
|
||||||
|
OperationRoot(T* data, const IndexType& ind) :
|
||||||
|
mDataPtr(data),
|
||||||
|
mIndex( ind ) { }
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
template <class OpClass>
|
||||||
|
OperationMaster<T,OpClass,Ranges...> OperationRoot<T,Ranges...>::operator=(const OpClass& in)
|
||||||
|
{
|
||||||
|
return OperationMaster<T,OpClass,Ranges...>(mDataPtr, in, mIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
OperationMaster<T,OperationRoot<T,Ranges...>,Ranges...>
|
||||||
|
OperationRoot<T,Ranges...>::operator=(const OperationRoot<T,Ranges...>& in)
|
||||||
|
{
|
||||||
|
return operator=<OperationRoot<T,Ranges...> >(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
template <class ET>
|
||||||
|
inline T OperationRoot<T,Ranges...>::get(ET pos) const
|
||||||
|
{
|
||||||
|
return mDataPtr[pos.val()+mOff];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
template <class ET>
|
||||||
|
inline const OperationRoot<T,Ranges...>& OperationRoot<T,Ranges...>::set(ET pos) const
|
||||||
|
{
|
||||||
|
mIndex = pos.val();
|
||||||
|
mOff = mIndex.pos();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
MExt<void> OperationRoot<T,Ranges...>::rootSteps(std::intptr_t iPtrNum) const
|
||||||
|
{
|
||||||
|
return MExt<void>(getStepSize( mIndex, iPtrNum ));
|
||||||
|
//return MExt<void>(getStepSize( mIndex.info(), iPtrNum ));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
template <class Expr>
|
||||||
|
Expr OperationRoot<T,Ranges...>::loop(Expr exp) const
|
||||||
|
{
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
T* OperationRoot<T,Ranges...>::data() const
|
||||||
|
{
|
||||||
|
return mDataPtr + mIndex().pos();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
template <class... Indices>
|
||||||
|
auto OperationRoot<T,Ranges...>::sl(const std::shared_ptr<Indices>&... inds)
|
||||||
|
-> Slice<T,typename Indices::RangeType...>
|
||||||
|
{
|
||||||
|
Slice<T,typename Indices::RangeType...> out(inds->range()...);
|
||||||
|
out.define(inds...) = *this;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************
|
||||||
|
* OperationValue *
|
||||||
|
************************/
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
OperationValue<T>::OperationValue(const T& val) : mVal(val) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
template <class ET>
|
||||||
|
inline T OperationValue<T>::get(ET pos) const
|
||||||
|
{
|
||||||
|
return mVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
template <class ET>
|
||||||
|
inline const OperationValue<T>& OperationValue<T>::set(ET pos) const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
MExt<void> OperationValue<T>::rootSteps(std::intptr_t iPtrNum) const
|
||||||
|
{
|
||||||
|
return MExt<void>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
template <class Expr>
|
||||||
|
Expr OperationValue<T>::loop(Expr exp) const
|
||||||
|
{
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************
|
||||||
|
* Operation *
|
||||||
|
*******************/
|
||||||
|
|
||||||
|
template <typename T, class OpFunction, class... Ops>
|
||||||
|
Operation<T,OpFunction,Ops...>::Operation(const Ops&... ops) :
|
||||||
|
mOps(ops...)
|
||||||
|
{
|
||||||
|
static_assert( FISSTATIC, "need function instance for non-static function" );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OpFunction, class... Ops>
|
||||||
|
Operation<T,OpFunction,Ops...>::Operation(std::shared_ptr<OpFunction> ff,
|
||||||
|
const Ops&... ops) :
|
||||||
|
mOps(ops...),
|
||||||
|
mF(ff)
|
||||||
|
{
|
||||||
|
static_assert( not FISSTATIC, "using instance of function supposed to be static" );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OpFunction, class... Ops>
|
||||||
|
template <class ET>
|
||||||
|
inline T Operation<T,OpFunction,Ops...>::get(ET pos) const
|
||||||
|
{
|
||||||
|
typedef std::tuple<Ops...> OpTuple;
|
||||||
|
return PackNum<sizeof...(Ops)-1>::
|
||||||
|
template mkOpExpr<SIZE,T,ET,OpTuple,OpFunction>(mF, pos, mOps);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OpFunction, class... Ops>
|
||||||
|
template <class ET>
|
||||||
|
inline const Operation<T,OpFunction,Ops...>& Operation<T,OpFunction,Ops...>::set(ET pos) const
|
||||||
|
{
|
||||||
|
PackNum<sizeof...(Ops)-1>::setOpPos(mOps,pos);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OpFunction, class... Ops>
|
||||||
|
auto Operation<T,OpFunction,Ops...>::rootSteps(std::intptr_t iPtrNum) const
|
||||||
|
-> decltype(PackNum<sizeof...(Ops)-1>::mkSteps(iPtrNum, mOps))
|
||||||
|
{
|
||||||
|
return PackNum<sizeof...(Ops)-1>::mkSteps(iPtrNum, mOps);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OpFunction, class... Ops>
|
||||||
|
template <class Expr>
|
||||||
|
auto Operation<T,OpFunction,Ops...>::loop(Expr exp) const
|
||||||
|
-> decltype(PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp ))
|
||||||
|
{
|
||||||
|
return PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* Contraction *
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
template <typename T, class Op, class IndexType>
|
||||||
|
Contraction<T,Op,IndexType>::Contraction(const Op& op, std::shared_ptr<IndexType> ind) :
|
||||||
|
mOp(op),
|
||||||
|
mInd(ind) {}
|
||||||
|
|
||||||
|
// forward loop !!!!
|
||||||
|
template <typename T, class Op, class IndexType>
|
||||||
|
template <class ET>
|
||||||
|
inline T Contraction<T,Op,IndexType>::get(ET pos) const
|
||||||
|
{
|
||||||
|
return mOp.template get<ET>(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Op, class IndexType>
|
||||||
|
template <class ET>
|
||||||
|
inline const Contraction<T,Op,IndexType>& Contraction<T,Op,IndexType>::set(ET pos) const
|
||||||
|
{
|
||||||
|
mOp.set(pos);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Op, class IndexType>
|
||||||
|
auto Contraction<T,Op,IndexType>::rootSteps(std::intptr_t iPtrNum) const
|
||||||
|
-> decltype(mOp.rootSteps(iPtrNum))
|
||||||
|
{
|
||||||
|
return mOp.rootSteps(iPtrNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Op, class IndexType>
|
||||||
|
template <class Expr>
|
||||||
|
auto Contraction<T,Op,IndexType>::loop(Expr exp) const -> decltype(mInd->iforh(1,exp))
|
||||||
|
{
|
||||||
|
return mInd->iforh(1,exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************
|
||||||
|
* SliceContraction *
|
||||||
|
**************************/
|
||||||
|
|
||||||
|
template <typename T, class Op, class... Indices>
|
||||||
|
SliceContraction<T,Op,Indices...>::SliceContraction(const Op& op,
|
||||||
|
std::shared_ptr<Indices>... ind) :
|
||||||
|
mOp(op),
|
||||||
|
mCont(std::make_shared<MultiArray<T,typename Indices::RangeType...> >(ind->range()...)),
|
||||||
|
mTarOp(*mCont,ind...)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
// forward loop !!!!
|
||||||
|
template <typename T, class Op, class... Indices>
|
||||||
|
template <class ET>
|
||||||
|
inline const MultiArray<T,typename Indices::RangeType...>&
|
||||||
|
SliceContraction<T,Op,Indices...>::get(ET pos) const
|
||||||
|
{
|
||||||
|
*mCont = 0;
|
||||||
|
mOp.set(pos);
|
||||||
|
mTarOp = mOp;
|
||||||
|
return *mCont;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Op, class... Indices>
|
||||||
|
template <class ET>
|
||||||
|
inline const SliceContraction<T,Op,Indices...>& SliceContraction<T,Op,Indices...>::set(ET pos) const
|
||||||
|
{
|
||||||
|
mOp.set(pos);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Op, class... Indices>
|
||||||
|
auto SliceContraction<T,Op,Indices...>::rootSteps(std::intptr_t iPtrNum) const
|
||||||
|
-> decltype(mOp.rootSteps(iPtrNum))
|
||||||
|
{
|
||||||
|
return mOp.rootSteps(iPtrNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Op, class... Indices>
|
||||||
|
template <class Expr>
|
||||||
|
auto SliceContraction<T,Op,Indices...>::loop(Expr exp) const -> decltype(mOp.loop(exp))
|
||||||
|
{
|
||||||
|
return mOp.loop(exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -505,551 +505,6 @@ namespace MultiArrayTools
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================= *
|
|
||||||
* --- TEMPLATE CODE --- *
|
|
||||||
* ========================= */
|
|
||||||
|
|
||||||
namespace MultiArrayTools
|
|
||||||
{
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
using namespace MultiArrayHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************
|
|
||||||
* OperationTemplate *
|
|
||||||
***************************/
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <class Second>
|
|
||||||
auto OperationBase<T,OperationClass>::operator+(const OperationBase<T,Second>& in) const
|
|
||||||
-> Operation<T,plus<T>,OperationClass,Second>
|
|
||||||
{
|
|
||||||
return Operation<T,plus<T>,OperationClass,Second>(THIS(), in.THIS());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <class Second>
|
|
||||||
auto OperationBase<T,OperationClass>::operator-(const OperationBase<T,Second>& in) const
|
|
||||||
-> Operation<T,minus<T>,OperationClass,Second>
|
|
||||||
{
|
|
||||||
return Operation<T,minus<T>,OperationClass,Second>(THIS(), in.THIS());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <class Second>
|
|
||||||
auto OperationBase<T,OperationClass>::operator*(const OperationBase<T,Second>& in) const
|
|
||||||
-> Operation<T,multiplies<T>,OperationClass,Second>
|
|
||||||
{
|
|
||||||
return Operation<T,multiplies<T>,OperationClass,Second>(THIS(), in.THIS());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <class Second>
|
|
||||||
auto OperationBase<T,OperationClass>::operator/(const OperationBase<T,Second>& in) const
|
|
||||||
-> Operation<T,divides<T>,OperationClass,Second>
|
|
||||||
{
|
|
||||||
return Operation<T,divides<T>,OperationClass,Second>(THIS(), in.THIS());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <class IndexType>
|
|
||||||
auto OperationBase<T,OperationClass>::c(const std::shared_ptr<IndexType>& ind) const
|
|
||||||
-> Contraction<T,OperationClass,IndexType>
|
|
||||||
{
|
|
||||||
return Contraction<T,OperationClass,IndexType>(THIS(), ind);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <class... Indices>
|
|
||||||
auto OperationBase<T,OperationClass>::sl(const std::shared_ptr<Indices>&... inds) const
|
|
||||||
-> ConstSlice<T,typename Indices::RangeType...>
|
|
||||||
{
|
|
||||||
ConstSlice<T,typename Indices::RangeType...> out(inds->range()...);
|
|
||||||
out.define(inds...) = THIS();
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <class... Indices>
|
|
||||||
auto OperationBase<T,OperationClass>::slc(const std::shared_ptr<Indices>&... inds) const
|
|
||||||
-> SliceContraction<T,OperationClass,Indices...>
|
|
||||||
{
|
|
||||||
return SliceContraction<T,OperationClass,Indices...>
|
|
||||||
(THIS(), inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************
|
|
||||||
* OperationMaster::AssignmentExpr *
|
|
||||||
*****************************************/
|
|
||||||
|
|
||||||
template <typename T, class OpClass, class... Ranges>
|
|
||||||
OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::
|
|
||||||
AssignmentExpr(OperationMaster& m, const OpClass& sec) :
|
|
||||||
mM(m), mSec(sec) {}
|
|
||||||
|
|
||||||
template <typename T, class OpClass, class... Ranges>
|
|
||||||
inline void OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::
|
|
||||||
operator()(size_t start, ExtType last) const
|
|
||||||
{
|
|
||||||
//VCHECK(mSec.template get<ExtType>(last));
|
|
||||||
mM.add(start, mSec.template get<ExtType>(last) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OpClass, class... Ranges>
|
|
||||||
typename OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::ExtType
|
|
||||||
OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::
|
|
||||||
rootSteps(std::intptr_t iPtrNum) const
|
|
||||||
{
|
|
||||||
return mSec.rootSteps(iPtrNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************
|
|
||||||
* OperationMaster *
|
|
||||||
*************************/
|
|
||||||
|
|
||||||
template <typename T, class OpClass, class... Ranges>
|
|
||||||
OperationMaster<T,OpClass,Ranges...>::
|
|
||||||
OperationMaster(MutableMultiArrayBase<T,Ranges...>& ma, const OpClass& second,
|
|
||||||
IndexType& index) :
|
|
||||||
mSecond(second), mDataPtr(ma.data()),
|
|
||||||
mIndex(index)
|
|
||||||
{
|
|
||||||
performAssignment(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OpClass, class... Ranges>
|
|
||||||
OperationMaster<T,OpClass,Ranges...>::
|
|
||||||
OperationMaster(T* data, const OpClass& second,
|
|
||||||
IndexType& index) :
|
|
||||||
mSecond(second), mDataPtr(data),
|
|
||||||
mIndex(index)
|
|
||||||
{
|
|
||||||
performAssignment(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OpClass, class... Ranges>
|
|
||||||
void OperationMaster<T,OpClass,Ranges...>::performAssignment(std::intptr_t blockIndexNum)
|
|
||||||
{
|
|
||||||
AssignmentExpr ae(*this, mSecond); // Expression to be executed within loop
|
|
||||||
const auto loop = mSecond.template loop<decltype(mIndex.ifor(1,ae))>( mIndex.ifor(1,ae) );
|
|
||||||
// hidden Loops outside ! -> auto vectorizable
|
|
||||||
loop(); // execute overall loop(s) and so internal hidden loops and so the inherited expressions
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OpClass, class... Ranges>
|
|
||||||
inline T OperationMaster<T,OpClass,Ranges...>::get(size_t pos) const
|
|
||||||
{
|
|
||||||
return mDataPtr[pos];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************
|
|
||||||
* ConstOperationRoot *
|
|
||||||
****************************/
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
ConstOperationRoot<T,Ranges...>::
|
|
||||||
ConstOperationRoot(const MultiArrayBase<T,Ranges...>& ma,
|
|
||||||
const std::shared_ptr<typename Ranges::IndexType>&... indices) :
|
|
||||||
mDataPtr(ma.data()),
|
|
||||||
mIndex( ma.begin() )
|
|
||||||
{
|
|
||||||
//VCHECK(ma.data());
|
|
||||||
mIndex(indices...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
ConstOperationRoot<T,Ranges...>::
|
|
||||||
ConstOperationRoot(std::shared_ptr<MultiArrayBase<T,Ranges...> > maptr,
|
|
||||||
const std::shared_ptr<typename Ranges::IndexType>&... indices) :
|
|
||||||
mDataPtr(maptr->data()),
|
|
||||||
mIndex(maptr->begin()),
|
|
||||||
mMaPtr(maptr)
|
|
||||||
{
|
|
||||||
mIndex(indices...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
ConstOperationRoot<T,Ranges...>::
|
|
||||||
ConstOperationRoot(const T* data, const IndexType& ind) :
|
|
||||||
mDataPtr(data),
|
|
||||||
mIndex( ind ) { }
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class ET>
|
|
||||||
inline T ConstOperationRoot<T,Ranges...>::get(ET pos) const
|
|
||||||
{
|
|
||||||
return mDataPtr[pos.val()+mOff];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class ET>
|
|
||||||
inline const ConstOperationRoot<T,Ranges...>& ConstOperationRoot<T,Ranges...>::set(ET pos) const
|
|
||||||
{
|
|
||||||
mIndex = pos.val();
|
|
||||||
mOff = mIndex.pos();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
const T* ConstOperationRoot<T,Ranges...>::data() const
|
|
||||||
{
|
|
||||||
return mDataPtr + mIndex().pos();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
MExt<void> ConstOperationRoot<T,Ranges...>::rootSteps(std::intptr_t iPtrNum) const
|
|
||||||
{
|
|
||||||
return MExt<void>(getStepSize( mIndex, iPtrNum ));
|
|
||||||
//return MExt<void>(getStepSize( getRootIndices( mIndex->info() ), iPtrNum ));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class Expr>
|
|
||||||
Expr ConstOperationRoot<T,Ranges...>::loop(Expr exp) const
|
|
||||||
{
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************
|
|
||||||
* StaticCast *
|
|
||||||
********************/
|
|
||||||
|
|
||||||
template <typename T, class Op>
|
|
||||||
StaticCast<T,Op>::StaticCast(const Op& op) : mOp(op) {}
|
|
||||||
|
|
||||||
template <typename T, class Op>
|
|
||||||
template <class ET>
|
|
||||||
inline T StaticCast<T,Op>::get(ET pos) const
|
|
||||||
{
|
|
||||||
return static_cast<T>( mOp.get(pos) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Op>
|
|
||||||
template <class ET>
|
|
||||||
inline const StaticCast<T,Op>& StaticCast<T,Op>::set(ET pos) const
|
|
||||||
{
|
|
||||||
mOp.set(pos);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Op>
|
|
||||||
auto StaticCast<T,Op>::rootSteps(std::intptr_t iPtrNum) const
|
|
||||||
-> decltype(mOp.rootSteps(iPtrNum))
|
|
||||||
{
|
|
||||||
return mOp.rootSteps(iPtrNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Op>
|
|
||||||
template <class Expr>
|
|
||||||
Expr StaticCast<T,Op>::loop(Expr exp) const
|
|
||||||
{
|
|
||||||
return mOp.loop(exp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************
|
|
||||||
* MetaOperationRoot *
|
|
||||||
****************************/
|
|
||||||
|
|
||||||
template <class... Ranges>
|
|
||||||
MetaOperationRoot<Ranges...>::
|
|
||||||
MetaOperationRoot(const IndexType& ind) :
|
|
||||||
mIndex( ind ) { }
|
|
||||||
|
|
||||||
template <class... Ranges>
|
|
||||||
template <class ET>
|
|
||||||
inline typename MetaOperationRoot<Ranges...>::value_type
|
|
||||||
MetaOperationRoot<Ranges...>::get(ET pos) const
|
|
||||||
{
|
|
||||||
//VCHECK(pos.val());
|
|
||||||
//VCHECK(mDataPtr);
|
|
||||||
//VCHECK(mDataPtr[pos.val()])
|
|
||||||
return mIndex.meta(pos.val());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Ranges>
|
|
||||||
template <class ET>
|
|
||||||
inline const MetaOperationRoot<Ranges...>& MetaOperationRoot<Ranges...>::set(ET pos) const
|
|
||||||
{
|
|
||||||
mIndex = pos.val();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Ranges>
|
|
||||||
MExt<void> MetaOperationRoot<Ranges...>::rootSteps(std::intptr_t iPtrNum) const
|
|
||||||
{
|
|
||||||
return MExt<void>(getStepSize( mIndex, iPtrNum ));
|
|
||||||
//return MExt<void>(getStepSize( getRootIndices( mIndex->info() ), iPtrNum ));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class... Ranges>
|
|
||||||
template <class Expr>
|
|
||||||
Expr MetaOperationRoot<Ranges...>::loop(Expr exp) const
|
|
||||||
{
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************
|
|
||||||
* OperationRoot *
|
|
||||||
***********************/
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
OperationRoot<T,Ranges...>::
|
|
||||||
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
|
||||||
const std::shared_ptr<typename Ranges::IndexType>&... indices) :
|
|
||||||
mDataPtr(ma.data()),
|
|
||||||
mIndex( ma.begin() )
|
|
||||||
{
|
|
||||||
mIndex(indices...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
OperationRoot<T,Ranges...>::
|
|
||||||
OperationRoot(T* data, const IndexType& ind) :
|
|
||||||
mDataPtr(data),
|
|
||||||
mIndex( ind ) { }
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class OpClass>
|
|
||||||
OperationMaster<T,OpClass,Ranges...> OperationRoot<T,Ranges...>::operator=(const OpClass& in)
|
|
||||||
{
|
|
||||||
return OperationMaster<T,OpClass,Ranges...>(mDataPtr, in, mIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
OperationMaster<T,OperationRoot<T,Ranges...>,Ranges...>
|
|
||||||
OperationRoot<T,Ranges...>::operator=(const OperationRoot<T,Ranges...>& in)
|
|
||||||
{
|
|
||||||
return operator=<OperationRoot<T,Ranges...> >(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class ET>
|
|
||||||
inline T OperationRoot<T,Ranges...>::get(ET pos) const
|
|
||||||
{
|
|
||||||
return mDataPtr[pos.val()+mOff];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class ET>
|
|
||||||
inline const OperationRoot<T,Ranges...>& OperationRoot<T,Ranges...>::set(ET pos) const
|
|
||||||
{
|
|
||||||
mIndex = pos.val();
|
|
||||||
mOff = mIndex.pos();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
MExt<void> OperationRoot<T,Ranges...>::rootSteps(std::intptr_t iPtrNum) const
|
|
||||||
{
|
|
||||||
return MExt<void>(getStepSize( mIndex, iPtrNum ));
|
|
||||||
//return MExt<void>(getStepSize( mIndex.info(), iPtrNum ));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class Expr>
|
|
||||||
Expr OperationRoot<T,Ranges...>::loop(Expr exp) const
|
|
||||||
{
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
T* OperationRoot<T,Ranges...>::data() const
|
|
||||||
{
|
|
||||||
return mDataPtr + mIndex().pos();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class... Indices>
|
|
||||||
auto OperationRoot<T,Ranges...>::sl(const std::shared_ptr<Indices>&... inds)
|
|
||||||
-> Slice<T,typename Indices::RangeType...>
|
|
||||||
{
|
|
||||||
Slice<T,typename Indices::RangeType...> out(inds->range()...);
|
|
||||||
out.define(inds...) = *this;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* OperationValue *
|
|
||||||
************************/
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
OperationValue<T>::OperationValue(const T& val) : mVal(val) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
template <class ET>
|
|
||||||
inline T OperationValue<T>::get(ET pos) const
|
|
||||||
{
|
|
||||||
return mVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
template <class ET>
|
|
||||||
inline const OperationValue<T>& OperationValue<T>::set(ET pos) const
|
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
MExt<void> OperationValue<T>::rootSteps(std::intptr_t iPtrNum) const
|
|
||||||
{
|
|
||||||
return MExt<void>(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
template <class Expr>
|
|
||||||
Expr OperationValue<T>::loop(Expr exp) const
|
|
||||||
{
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*******************
|
|
||||||
* Operation *
|
|
||||||
*******************/
|
|
||||||
|
|
||||||
template <typename T, class OpFunction, class... Ops>
|
|
||||||
Operation<T,OpFunction,Ops...>::Operation(const Ops&... ops) :
|
|
||||||
mOps(ops...)
|
|
||||||
{
|
|
||||||
static_assert( FISSTATIC, "need function instance for non-static function" );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OpFunction, class... Ops>
|
|
||||||
Operation<T,OpFunction,Ops...>::Operation(std::shared_ptr<OpFunction> ff,
|
|
||||||
const Ops&... ops) :
|
|
||||||
mOps(ops...),
|
|
||||||
mF(ff)
|
|
||||||
{
|
|
||||||
static_assert( not FISSTATIC, "using instance of function supposed to be static" );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OpFunction, class... Ops>
|
|
||||||
template <class ET>
|
|
||||||
inline T Operation<T,OpFunction,Ops...>::get(ET pos) const
|
|
||||||
{
|
|
||||||
typedef std::tuple<Ops...> OpTuple;
|
|
||||||
return PackNum<sizeof...(Ops)-1>::
|
|
||||||
template mkOpExpr<SIZE,T,ET,OpTuple,OpFunction>(mF, pos, mOps);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OpFunction, class... Ops>
|
|
||||||
template <class ET>
|
|
||||||
inline const Operation<T,OpFunction,Ops...>& Operation<T,OpFunction,Ops...>::set(ET pos) const
|
|
||||||
{
|
|
||||||
PackNum<sizeof...(Ops)-1>::setOpPos(mOps,pos);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OpFunction, class... Ops>
|
|
||||||
auto Operation<T,OpFunction,Ops...>::rootSteps(std::intptr_t iPtrNum) const
|
|
||||||
-> decltype(PackNum<sizeof...(Ops)-1>::mkSteps(iPtrNum, mOps))
|
|
||||||
{
|
|
||||||
return PackNum<sizeof...(Ops)-1>::mkSteps(iPtrNum, mOps);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OpFunction, class... Ops>
|
|
||||||
template <class Expr>
|
|
||||||
auto Operation<T,OpFunction,Ops...>::loop(Expr exp) const
|
|
||||||
-> decltype(PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp ))
|
|
||||||
{
|
|
||||||
return PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* Contraction *
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
template <typename T, class Op, class IndexType>
|
|
||||||
Contraction<T,Op,IndexType>::Contraction(const Op& op, std::shared_ptr<IndexType> ind) :
|
|
||||||
mOp(op),
|
|
||||||
mInd(ind) {}
|
|
||||||
|
|
||||||
// forward loop !!!!
|
|
||||||
template <typename T, class Op, class IndexType>
|
|
||||||
template <class ET>
|
|
||||||
inline T Contraction<T,Op,IndexType>::get(ET pos) const
|
|
||||||
{
|
|
||||||
return mOp.template get<ET>(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Op, class IndexType>
|
|
||||||
template <class ET>
|
|
||||||
inline const Contraction<T,Op,IndexType>& Contraction<T,Op,IndexType>::set(ET pos) const
|
|
||||||
{
|
|
||||||
mOp.set(pos);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Op, class IndexType>
|
|
||||||
auto Contraction<T,Op,IndexType>::rootSteps(std::intptr_t iPtrNum) const
|
|
||||||
-> decltype(mOp.rootSteps(iPtrNum))
|
|
||||||
{
|
|
||||||
return mOp.rootSteps(iPtrNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Op, class IndexType>
|
|
||||||
template <class Expr>
|
|
||||||
auto Contraction<T,Op,IndexType>::loop(Expr exp) const -> decltype(mInd->iforh(1,exp))
|
|
||||||
{
|
|
||||||
return mInd->iforh(1,exp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************
|
|
||||||
* SliceContraction *
|
|
||||||
**************************/
|
|
||||||
|
|
||||||
template <typename T, class Op, class... Indices>
|
|
||||||
SliceContraction<T,Op,Indices...>::SliceContraction(const Op& op,
|
|
||||||
std::shared_ptr<Indices>... ind) :
|
|
||||||
mOp(op),
|
|
||||||
mCont(std::make_shared<MultiArray<T,typename Indices::RangeType...> >(ind->range()...)),
|
|
||||||
mTarOp(*mCont,ind...)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
// forward loop !!!!
|
|
||||||
template <typename T, class Op, class... Indices>
|
|
||||||
template <class ET>
|
|
||||||
inline const MultiArray<T,typename Indices::RangeType...>&
|
|
||||||
SliceContraction<T,Op,Indices...>::get(ET pos) const
|
|
||||||
{
|
|
||||||
*mCont = 0;
|
|
||||||
mOp.set(pos);
|
|
||||||
mTarOp = mOp;
|
|
||||||
return *mCont;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Op, class... Indices>
|
|
||||||
template <class ET>
|
|
||||||
inline const SliceContraction<T,Op,Indices...>& SliceContraction<T,Op,Indices...>::set(ET pos) const
|
|
||||||
{
|
|
||||||
mOp.set(pos);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Op, class... Indices>
|
|
||||||
auto SliceContraction<T,Op,Indices...>::rootSteps(std::intptr_t iPtrNum) const
|
|
||||||
-> decltype(mOp.rootSteps(iPtrNum))
|
|
||||||
{
|
|
||||||
return mOp.rootSteps(iPtrNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Op, class... Indices>
|
|
||||||
template <class Expr>
|
|
||||||
auto SliceContraction<T,Op,Indices...>::loop(Expr exp) const -> decltype(mOp.loop(exp))
|
|
||||||
{
|
|
||||||
return mOp.loop(exp);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "type_operations.h"
|
#include "type_operations.h"
|
||||||
|
|
||||||
|
|
448
src/include/ranges/dynamic_range.cc.h
Normal file
448
src/include/ranges/dynamic_range.cc.h
Normal file
|
@ -0,0 +1,448 @@
|
||||||
|
|
||||||
|
//#include "ranges/dynamic_range.h"
|
||||||
|
//#include "ranges/dynamic_meta.h"
|
||||||
|
|
||||||
|
#include "rpack_num.h"
|
||||||
|
|
||||||
|
namespace MultiArrayTools
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
using namespace MultiArrayHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************
|
||||||
|
* DynamicRangeFactory *
|
||||||
|
****************************/
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
template <class... RangeTypes>
|
||||||
|
DynamicRangeFactory<EC>::DynamicRangeFactory(const std::tuple<std::shared_ptr<RangeTypes>...>& origs)
|
||||||
|
{
|
||||||
|
mProd = std::shared_ptr<oType>( new DynamicRange<EC>( origs ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
template <class... RangeTypes>
|
||||||
|
DynamicRangeFactory<EC>::DynamicRangeFactory(std::shared_ptr<RangeTypes>... origs)
|
||||||
|
{
|
||||||
|
mProd = std::shared_ptr<oType>( new DynamicRange<EC>( origs... ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
template <class Range>
|
||||||
|
void DynamicRangeFactory<EC>::append(std::shared_ptr<Range> r)
|
||||||
|
{
|
||||||
|
if(mProductCreated){
|
||||||
|
|
||||||
|
mProd = std::shared_ptr<oType>( new DynamicRange<EC>( *std::dynamic_pointer_cast<oType>(mProd) ) );
|
||||||
|
mProductCreated = false;
|
||||||
|
}
|
||||||
|
std::dynamic_pointer_cast<oType>(mProd)->mOrig.push_back(r);
|
||||||
|
std::dynamic_pointer_cast<oType>(mProd)->mSize *= r->size();
|
||||||
|
std::dynamic_pointer_cast<oType>(mProd)->mEmpty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
DynamicRangeFactory<EC>::DynamicRangeFactory()
|
||||||
|
{
|
||||||
|
mProd = std::shared_ptr<oType>( new DynamicRange<EC>() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// INSTANCIATE IF NEEDED!!
|
||||||
|
template <class EC>
|
||||||
|
std::map<std::shared_ptr<RangeBase>,std::vector<std::intptr_t> > DynamicRangeFactory<EC>::mAleadyCreated;
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
std::shared_ptr<RangeBase> DynamicRangeFactory<EC>::checkIfCreated(const std::vector<std::shared_ptr<RangeBase> >& pvec)
|
||||||
|
{
|
||||||
|
std::shared_ptr<RangeBase> out;
|
||||||
|
bool check = false;
|
||||||
|
for(auto& x: mAleadyCreated){
|
||||||
|
if(x.second.size() == pvec.size()){
|
||||||
|
check = true;
|
||||||
|
for(size_t i = 0; i != x.second.size(); ++i){
|
||||||
|
if(x.second[i] != reinterpret_cast<std::intptr_t>( pvec[i].get() ) ){
|
||||||
|
check = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(check == true){
|
||||||
|
out = x.first;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(not check){
|
||||||
|
std::vector<std::intptr_t> app(pvec.size());
|
||||||
|
for(size_t i = 0; i != app.size(); ++i){
|
||||||
|
app[i] = reinterpret_cast<std::intptr_t>( pvec[i].get() );
|
||||||
|
}
|
||||||
|
mAleadyCreated[mProd] = app;
|
||||||
|
out = mProd;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
std::shared_ptr<RangeBase> DynamicRangeFactory<EC>::create()
|
||||||
|
{
|
||||||
|
mProd = checkIfCreated(std::dynamic_pointer_cast<DynamicRange<EC>>(mProd)->mOrig);
|
||||||
|
setSelf();
|
||||||
|
mProductCreated = true;
|
||||||
|
return mProd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DynamicIndex *
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
DynamicIndex<EC>::DynamicIndex(const std::shared_ptr<DynamicRange<EC> >& range) :
|
||||||
|
IndexInterface<DynamicIndex,MetaType>(range, 0)//,
|
||||||
|
//mExplicitRangePtr(std::dynamic_pointer_cast<RangeType>(IB::mRangePtr)),
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
IndexType DynamicIndex<EC>::type() const
|
||||||
|
{
|
||||||
|
return IndexType::SINGLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
DynamicIndex<EC>& DynamicIndex<EC>::operator=(size_t pos)
|
||||||
|
{
|
||||||
|
IB::mPos = pos;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
DynamicIndex<EC>& DynamicIndex<EC>::operator++()
|
||||||
|
{
|
||||||
|
size_t ipos = mIVec.size()-1;
|
||||||
|
auto& ii = mIVec[ipos].first;
|
||||||
|
auto& jj = mIVec[ipos-1].first;
|
||||||
|
while(ii->pos() == ii->max()-1 and ipos != 0) {
|
||||||
|
(*ii) = 0;
|
||||||
|
++(*jj);
|
||||||
|
--ipos;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
DynamicIndex<EC>& DynamicIndex<EC>::operator--()
|
||||||
|
{
|
||||||
|
size_t ipos = mIVec.size()-1;
|
||||||
|
auto& ii = mIVec[ipos].first;
|
||||||
|
auto& jj = mIVec[ipos-1].first;
|
||||||
|
while(ii->pos() == 0 and ipos != 0) {
|
||||||
|
(*ii) = ii->max()-1;
|
||||||
|
--(*jj);
|
||||||
|
--ipos;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
DynamicIndex<EC>& DynamicIndex<EC>::operator()(const IVecT& ivec)
|
||||||
|
{
|
||||||
|
mIVec = ivec;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
int DynamicIndex<EC>::pp(std::intptr_t idxPtrNum)
|
||||||
|
{
|
||||||
|
++(*this);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
int DynamicIndex<EC>::mm(std::intptr_t idxPtrNum)
|
||||||
|
{
|
||||||
|
--(*this);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
std::string DynamicIndex<EC>::stringMeta() const
|
||||||
|
{
|
||||||
|
return std::dynamic_pointer_cast<DynamicRange<EC> const>( IB::mRangePtr )->stringMeta(IB::mPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
typename DynamicIndex<EC>::MetaType DynamicIndex<EC>::meta() const
|
||||||
|
{
|
||||||
|
return std::dynamic_pointer_cast<DynamicRange<EC> const>( IB::mRangePtr )->get(IB::mPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
const typename DynamicIndex<EC>::MetaType* DynamicIndex<EC>::metaPtr() const
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
bool DynamicIndex<EC>::isMeta(const MetaType& metaPos) const
|
||||||
|
{
|
||||||
|
return mExplicitRangePtr->isMeta(metaPos);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
DynamicIndex<EC>& DynamicIndex<EC>::at(const MetaType& metaPos)
|
||||||
|
{
|
||||||
|
(*this) = std::dynamic_pointer_cast<DynamicRange<EC> const>( IB::mRangePtr )->getMeta( metaPos );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
size_t DynamicIndex<EC>::posAt(const MetaType& metaPos) const
|
||||||
|
{
|
||||||
|
return std::dynamic_pointer_cast<DynamicRange<EC> const>( IB::mRangePtr )->getMeta( metaPos );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
size_t DynamicIndex<EC>::dim() const // = 1
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
bool DynamicIndex<EC>::last() const
|
||||||
|
{
|
||||||
|
return IB::mPos == IB::mMax - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
bool DynamicIndex<EC>::first() const
|
||||||
|
{
|
||||||
|
return IB::mPos == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
const IndexW<EC>& DynamicIndex<EC>::get(size_t n) const
|
||||||
|
{
|
||||||
|
return *mIVec[n].first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
std::shared_ptr<typename DynamicIndex<EC>::RangeType> DynamicIndex<EC>::range()
|
||||||
|
{
|
||||||
|
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
template <size_t N>
|
||||||
|
void DynamicIndex<EC>::getPtr() {}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
size_t DynamicIndex<EC>::getStepSize(size_t n) const
|
||||||
|
{
|
||||||
|
return mIVec[n].second;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
std::string DynamicIndex<EC>::id() const
|
||||||
|
{
|
||||||
|
return std::string("dyn") + std::to_string(IB::mId);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
void DynamicIndex<EC>::print(size_t offset)
|
||||||
|
{
|
||||||
|
if(offset == 0){
|
||||||
|
std::cout << " === " << std::endl;
|
||||||
|
}
|
||||||
|
for(size_t j = 0; j != offset; ++j) { std::cout << "\t"; }
|
||||||
|
std::cout << id() << "[" << reinterpret_cast<std::intptr_t>(this)
|
||||||
|
<< "](" << IB::mRangePtr << "): " /*<< meta().first*/ << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
inline DynamicExpression DynamicIndex<EC>::mkFor(size_t i, size_t step,
|
||||||
|
DynamicExpression ex, bool hidden) const
|
||||||
|
{
|
||||||
|
if(i != 0){
|
||||||
|
auto& ii = *mIVec[i].first;
|
||||||
|
return mkFor(i-1, step, hidden ? ii.iforh(step, ex) : ii.ifor(step, ex));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto& ii = *mIVec[0].first;
|
||||||
|
return hidden ? ii.iforh(step, ex) : ii.ifor(step, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
template <class Expr>
|
||||||
|
auto DynamicIndex<EC>::ifor(size_t step, Expr ex) const
|
||||||
|
-> DynamicExpression
|
||||||
|
{
|
||||||
|
DynamicExpression expr(std::make_shared<Expr>(ex));
|
||||||
|
return mkFor(mIVec.size()-1, step, expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
template <class Expr>
|
||||||
|
auto DynamicIndex<EC>::iforh(size_t step, Expr ex) const
|
||||||
|
-> DynamicExpression
|
||||||
|
{
|
||||||
|
DynamicExpression expr(std::make_shared<Expr>(ex));
|
||||||
|
return mkFor(mIVec.size()-1, step, expr, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***********************
|
||||||
|
* DynamicRange *
|
||||||
|
***********************/
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
typename DynamicRange<EC>::MetaType DynamicRange<EC>::get(size_t pos) const
|
||||||
|
{
|
||||||
|
return MetaType(); // !!!
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
size_t DynamicRange<EC>::getMeta(const MetaType& metaPos) const
|
||||||
|
{
|
||||||
|
return 0; // !!!
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
size_t DynamicRange<EC>::size() const
|
||||||
|
{
|
||||||
|
return mSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
size_t DynamicRange<EC>::dim() const
|
||||||
|
{
|
||||||
|
return mOrig.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
SpaceType DynamicRange<EC>::spaceType() const
|
||||||
|
{
|
||||||
|
return SpaceType::DYN;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
bool DynamicRange<EC>::isEmpty() const
|
||||||
|
{
|
||||||
|
return mEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
std::string DynamicRange<EC>::stringMeta(size_t pos) const
|
||||||
|
{
|
||||||
|
std::string out = "[ ";
|
||||||
|
//size_t xpos = pos;
|
||||||
|
for(size_t i = mOrig.size(); i != 0; --i) {
|
||||||
|
auto& x = mOrig[i-1];
|
||||||
|
const size_t redpos = pos % x->size();
|
||||||
|
out = ( (i == mOrig.size()) ? out : out + " , " ) + x->stringMeta(redpos);
|
||||||
|
pos -= redpos;
|
||||||
|
pos /= x->size();
|
||||||
|
}
|
||||||
|
out += " ]";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
std::vector<char> DynamicRange<EC>::data() const
|
||||||
|
{
|
||||||
|
DataHeader h;
|
||||||
|
h.spaceType = static_cast<int>( SpaceType::DYN );
|
||||||
|
h.metaSize = mOrig.size();
|
||||||
|
h.multiple = 1;
|
||||||
|
std::vector<char> out;
|
||||||
|
char* hcp = reinterpret_cast<char*>(&h);
|
||||||
|
out.insert(out.end(), hcp, hcp + sizeof(DataHeader));
|
||||||
|
for(auto& x: mOrig){
|
||||||
|
auto part = x->data();
|
||||||
|
out.insert(out.end(), part.begin(), part.end());
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
typename DynamicRange<EC>::IndexType DynamicRange<EC>::begin() const
|
||||||
|
{
|
||||||
|
DynamicIndex<EC> i
|
||||||
|
(std::dynamic_pointer_cast<DynamicRange>
|
||||||
|
( std::shared_ptr<RangeBase>(RB::mThis) ) );
|
||||||
|
i = 0;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
typename DynamicRange<EC>::IndexType DynamicRange<EC>::end() const
|
||||||
|
{
|
||||||
|
DynamicIndex<EC> i
|
||||||
|
(std::dynamic_pointer_cast<DynamicRange>
|
||||||
|
( std::shared_ptr<RangeBase>(RB::mThis) ) );
|
||||||
|
i = size();
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
std::shared_ptr<RangeBase> DynamicRange<EC>::sub(size_t num) const
|
||||||
|
{
|
||||||
|
return mOrig.at(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
void DynamicRange<EC>::sreplace(const std::shared_ptr<RangeBase> in, size_t num)
|
||||||
|
{
|
||||||
|
assert(mOrig[num]->size() == in->size());
|
||||||
|
mOrig[num] = in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
template <class... RangeTypes>
|
||||||
|
DynamicRange<EC>::DynamicRange(const std::tuple<std::shared_ptr<RangeTypes>...>& origs) :
|
||||||
|
RangeInterface<DynamicIndex<EC>>()
|
||||||
|
{
|
||||||
|
RPackNum<sizeof...(RangeTypes)-1>::RangesToVec( origs, mOrig );
|
||||||
|
mSize = RPackNum<sizeof...(RangeTypes)-1>::getSize( origs );
|
||||||
|
if(sizeof...(RangeTypes)){
|
||||||
|
mEmpty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
template <class... RangeTypes>
|
||||||
|
DynamicRange<EC>::DynamicRange(std::shared_ptr<RangeTypes>... origs) :
|
||||||
|
RangeInterface<DynamicIndex<EC>>()
|
||||||
|
{
|
||||||
|
auto rst = std::make_tuple(origs...);
|
||||||
|
RPackNum<sizeof...(RangeTypes)-1>::RangesToVec( rst, mOrig );
|
||||||
|
mSize = RPackNum<sizeof...(RangeTypes)-1>::getSize( rst );
|
||||||
|
if(sizeof...(RangeTypes)){
|
||||||
|
mEmpty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
template <class Range>
|
||||||
|
std::shared_ptr<Range> DynamicRange<EC>::fullsub(size_t num) const
|
||||||
|
{
|
||||||
|
return std::dynamic_pointer_cast<Range>( mOrig.at(num) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EC>
|
||||||
|
template <class... Ranges>
|
||||||
|
std::shared_ptr<MultiRange<Ranges...> > DynamicRange<EC>::scast(SIZET<Ranges>... sizes) const
|
||||||
|
{
|
||||||
|
std::tuple<std::shared_ptr<Ranges>...> rtp;
|
||||||
|
RPackNum<sizeof...(Ranges)-1>::resolveRangeType(mOrig, rtp, 0, sizes...);
|
||||||
|
MultiRangeFactory<Ranges...> mrf(rtp);
|
||||||
|
return std::dynamic_pointer_cast<MultiRange<Ranges...> >( mrf.create() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // end namespace MultiArrayTools
|
|
@ -2,6 +2,8 @@
|
||||||
#ifndef __dynamic_range_h__
|
#ifndef __dynamic_range_h__
|
||||||
#define __dynamic_range_h__
|
#define __dynamic_range_h__
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#include "ranges/rbase_def.h"
|
#include "ranges/rbase_def.h"
|
||||||
#include "ranges/range_base.h"
|
#include "ranges/range_base.h"
|
||||||
#include "ranges/index_base.h"
|
#include "ranges/index_base.h"
|
||||||
|
@ -9,7 +11,7 @@
|
||||||
#include "xfor/xfor.h"
|
#include "xfor/xfor.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "ranges/rpheader.h"
|
//#include "ranges/rpheader.h"
|
||||||
#include "ranges/x_to_string.h"
|
#include "ranges/x_to_string.h"
|
||||||
#include "ranges/type_map.h"
|
#include "ranges/type_map.h"
|
||||||
|
|
||||||
|
@ -18,10 +20,13 @@
|
||||||
namespace MultiArrayTools
|
namespace MultiArrayTools
|
||||||
{
|
{
|
||||||
|
|
||||||
using MultiArrayHelper::DynamicalExpression;
|
using MultiArrayHelper::DynamicExpression;
|
||||||
|
|
||||||
|
template <class ExpressionCollection>
|
||||||
class IndexWrapperBase
|
class IndexWrapperBase
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
std::shared_ptr<ExpressionCollection> mEc;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
IndexWrapperBase() = default;
|
IndexWrapperBase() = default;
|
||||||
|
@ -60,15 +65,26 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
virtual std::intptr_t get() const = 0;
|
virtual std::intptr_t get() const = 0;
|
||||||
|
|
||||||
virtual DynamicalExpression ifor(size_t step, DynamicalExpression ex) const = 0;
|
template <class Expr>
|
||||||
virtual DynamicalExpression iforh(size_t step, DynamicalExpression ex) const = 0;
|
auto ifor(size_t step, Expr ex) const
|
||||||
|
-> decltype(mEc->ifor(step, ex))
|
||||||
|
{ return mEc->ifor(step, ex); }
|
||||||
|
|
||||||
|
template <class Expr>
|
||||||
|
auto iforh(size_t step, Expr ex) const
|
||||||
|
-> decltype(mEc->iforh(step, ex))
|
||||||
|
{ return mEc->iforh(step, ex); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef IndexWrapperBase IndexW;
|
template <class EC>
|
||||||
|
using IndexW = IndexWrapperBase<EC>;
|
||||||
|
|
||||||
template <class Index, class Expr>
|
template <class Index, class ExpressionCollection>
|
||||||
class IndexWrapper : public IndexWrapperBase
|
class IndexWrapper : public IndexWrapperBase<ExpressionCollection>
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
typedef IndexWrapperBase<ExpressionCollection> IWB;
|
||||||
protected:
|
protected:
|
||||||
IndexWrapper() = default;
|
IndexWrapper() = default;
|
||||||
|
|
||||||
|
@ -81,13 +97,14 @@ namespace MultiArrayTools
|
||||||
IndexWrapper& operator=(const IndexWrapper& in) = default;
|
IndexWrapper& operator=(const IndexWrapper& in) = default;
|
||||||
IndexWrapper& operator=(IndexWrapper&& in) = default;
|
IndexWrapper& operator=(IndexWrapper&& in) = default;
|
||||||
|
|
||||||
IndexWrapper(const std::shared_ptr<Index>& i) : mI(i) {}
|
IndexWrapper(const std::shared_ptr<Index>& i) : mI(i)
|
||||||
|
{ IWB::mEc = ExpressionCollection::make(mI); }
|
||||||
|
|
||||||
virtual IndexType type() const final { return mI->type(); }
|
virtual IndexType type() const final { return mI->type(); }
|
||||||
|
|
||||||
virtual IndexWrapperBase& operator=(size_t pos) final { (*mI) = pos; return *this; }
|
virtual IndexWrapper& operator=(size_t pos) final { (*mI) = pos; return *this; }
|
||||||
virtual IndexWrapperBase& operator++() final { ++(*mI); return *this; }
|
virtual IndexWrapper& operator++() final { ++(*mI); return *this; }
|
||||||
virtual IndexWrapperBase& operator--() final { --(*mI); return *this; }
|
virtual IndexWrapper& operator--() final { --(*mI); return *this; }
|
||||||
|
|
||||||
virtual size_t pos() const final { return mI->pos(); }
|
virtual size_t pos() const final { return mI->pos(); }
|
||||||
virtual size_t max() const final { return mI->max(); }
|
virtual size_t max() const final { return mI->max(); }
|
||||||
|
@ -98,7 +115,7 @@ namespace MultiArrayTools
|
||||||
virtual std::string stringMeta() const final { return mI->stringMeta(); }
|
virtual std::string stringMeta() const final { return mI->stringMeta(); }
|
||||||
virtual DynamicMetaT meta() const final { return DynamicMetaT(mI->meta()); }
|
virtual DynamicMetaT meta() const final { return DynamicMetaT(mI->meta()); }
|
||||||
virtual const DynamicMetaT* metaPtr() const final { return nullptr; }
|
virtual const DynamicMetaT* metaPtr() const final { return nullptr; }
|
||||||
IndexWrapperBase& at(const typename Index::MetaType& metaPos) { mI->at(metaPos); return *this; }
|
IndexWrapper& at(const typename Index::MetaType& metaPos) { mI->at(metaPos); return *this; }
|
||||||
size_t posAt(const typename Index::MetaType& metaPos) const { return mI->posAt(metaPos); }
|
size_t posAt(const typename Index::MetaType& metaPos) const { return mI->posAt(metaPos); }
|
||||||
|
|
||||||
//virtual bool isMeta(const U& metaPos) const final { return mI->isMeta(); }
|
//virtual bool isMeta(const U& metaPos) const final { return mI->isMeta(); }
|
||||||
|
@ -114,30 +131,28 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
virtual std::intptr_t get() const final { return reinterpret_cast<std::intptr_t>(mI.get()); }
|
virtual std::intptr_t get() const final { return reinterpret_cast<std::intptr_t>(mI.get()); }
|
||||||
|
|
||||||
virtual DynamicalExpression ifor(size_t step, DynamicalExpression ex) const final { return mI->ifor(step, ex); }
|
|
||||||
virtual DynamicalExpression iforh(size_t step, DynamicalExpression ex) const final { return mI->iforh(step, ex); }
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef SingleRange<size_t,SpaceType::DYN> DynamicRange;
|
//typedef SingleRange<size_t,SpaceType::DYN> DynamicRange;
|
||||||
|
|
||||||
class DynamicIndex : public IndexInterface<DynamicIndex,DynamicMetaT>
|
template <class EC>
|
||||||
|
class DynamicIndex : public IndexInterface<DynamicIndex<EC>,DynamicMetaT>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef std::vector<std::pair<std::shared_ptr<IndexW>,size_t>> IVecT;
|
typedef std::vector<std::pair<std::shared_ptr<IndexW<EC>>,size_t>> IVecT;
|
||||||
|
|
||||||
IVecT mIVec;
|
IVecT mIVec;
|
||||||
|
|
||||||
inline DynamicalExpression mkFor(size_t i, size_t step,
|
inline DynamicExpression mkFor(size_t i, size_t step,
|
||||||
DynamicalExpression ex, bool hidden = false) const;
|
DynamicExpression ex, bool hidden = false) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef IndexInterface<DynamicIndex,DynamicMetaT> IB;
|
typedef IndexInterface<DynamicIndex<EC>,DynamicMetaT> IB;
|
||||||
typedef DynamicMetaT MetaType;
|
typedef DynamicMetaT MetaType;
|
||||||
typedef DynamicRange RangeType;
|
typedef DynamicRange<EC> RangeType;
|
||||||
typedef DynamicIndex IType;
|
typedef DynamicIndex IType;
|
||||||
|
|
||||||
DynamicIndex(const std::shared_ptr<DynamicRange>& range);
|
DynamicIndex(const std::shared_ptr<RangeType>& range);
|
||||||
|
|
||||||
static constexpr IndexType sType() { return IndexType::SINGLE; }
|
static constexpr IndexType sType() { return IndexType::SINGLE; }
|
||||||
static constexpr size_t totalDim() { return 1; }
|
static constexpr size_t totalDim() { return 1; }
|
||||||
|
@ -168,7 +183,7 @@ namespace MultiArrayTools
|
||||||
bool last() const;
|
bool last() const;
|
||||||
bool first() const;
|
bool first() const;
|
||||||
|
|
||||||
const IndexW& get(size_t n) const;
|
const IndexW<EC>& get(size_t n) const;
|
||||||
|
|
||||||
std::shared_ptr<RangeType> range();
|
std::shared_ptr<RangeType> range();
|
||||||
|
|
||||||
|
@ -182,21 +197,22 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
template <class Expr>
|
template <class Expr>
|
||||||
auto ifor(size_t step, Expr ex) const
|
auto ifor(size_t step, Expr ex) const
|
||||||
-> DynamicalExpression;
|
-> DynamicExpression;
|
||||||
|
|
||||||
template <class Expr>
|
template <class Expr>
|
||||||
auto iforh(size_t step, Expr ex) const
|
auto iforh(size_t step, Expr ex) const
|
||||||
-> DynamicalExpression;
|
-> DynamicExpression;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// NOT THREAD SAVE!!
|
// NOT THREAD SAVE!!
|
||||||
|
template <class EC>
|
||||||
class DynamicRangeFactory : public RangeFactoryBase
|
class DynamicRangeFactory : public RangeFactoryBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef DynamicRange oType;
|
typedef DynamicRange<EC> oType;
|
||||||
|
|
||||||
DynamicRangeFactory();
|
DynamicRangeFactory();
|
||||||
|
|
||||||
|
@ -220,8 +236,8 @@ namespace MultiArrayTools
|
||||||
bool mProductCreated = false;
|
bool mProductCreated = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <class EC>
|
||||||
class SingleRange<size_t,SpaceType::DYN> : public RangeInterface<DynamicIndex>
|
class DynamicRange : public RangeInterface<DynamicIndex<EC>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static constexpr bool defaultable = true;
|
static constexpr bool defaultable = true;
|
||||||
|
@ -230,19 +246,19 @@ namespace MultiArrayTools
|
||||||
static constexpr bool HASMETACONT = false;
|
static constexpr bool HASMETACONT = false;
|
||||||
|
|
||||||
typedef RangeBase RB;
|
typedef RangeBase RB;
|
||||||
typedef DynamicIndex IndexType;
|
typedef DynamicIndex<EC> IndexType;
|
||||||
typedef DynamicRange RangeType;
|
typedef DynamicRange RangeType;
|
||||||
typedef DynamicMetaT MetaType;
|
typedef DynamicMetaT MetaType;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SingleRange() = default;
|
DynamicRange() = default;
|
||||||
SingleRange(const SingleRange& in) = default;
|
DynamicRange(const DynamicRange& in) = default;
|
||||||
|
|
||||||
template <class... RangeTypes>
|
template <class... RangeTypes>
|
||||||
SingleRange(const std::tuple<std::shared_ptr<RangeTypes>...>& origs);
|
DynamicRange(const std::tuple<std::shared_ptr<RangeTypes>...>& origs);
|
||||||
|
|
||||||
template <class... RangeTypes>
|
template <class... RangeTypes>
|
||||||
SingleRange(std::shared_ptr<RangeTypes>... origs);
|
DynamicRange(std::shared_ptr<RangeTypes>... origs);
|
||||||
|
|
||||||
size_t mSize = 1;
|
size_t mSize = 1;
|
||||||
bool mEmpty = true;
|
bool mEmpty = true;
|
||||||
|
@ -276,79 +292,36 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
bool isEmpty() const;
|
bool isEmpty() const;
|
||||||
|
|
||||||
friend DynamicRangeFactory;
|
friend DynamicRangeFactory<EC>;
|
||||||
|
|
||||||
static DynamicRangeFactory factory()
|
static DynamicRangeFactory<EC> factory()
|
||||||
{ return DynamicRangeFactory(); }
|
{ return DynamicRangeFactory<EC>(); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace MultiArrayTools
|
} // namespace MultiArrayTools
|
||||||
|
|
||||||
|
|
||||||
/* ========================= *
|
|
||||||
* --- TEMPLATE CODE --- *
|
|
||||||
* ========================= */
|
|
||||||
|
|
||||||
namespace MultiArrayTools
|
|
||||||
{
|
|
||||||
|
|
||||||
/***********************
|
|
||||||
* DynamicRange *
|
|
||||||
***********************/
|
|
||||||
|
|
||||||
template <class... RangeTypes>
|
|
||||||
DynamicRangeFactory::DynamicRangeFactory(const std::tuple<std::shared_ptr<RangeTypes>...>& origs)
|
|
||||||
{
|
|
||||||
mProd = std::shared_ptr<oType>( new DynamicRange( origs ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... RangeTypes>
|
|
||||||
DynamicRangeFactory::DynamicRangeFactory(std::shared_ptr<RangeTypes>... origs)
|
|
||||||
{
|
|
||||||
mProd = std::shared_ptr<oType>( new DynamicRange( origs... ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Range>
|
|
||||||
void DynamicRangeFactory::append(std::shared_ptr<Range> r)
|
|
||||||
{
|
|
||||||
if(mProductCreated){
|
|
||||||
|
|
||||||
mProd = std::shared_ptr<oType>( new DynamicRange( *std::dynamic_pointer_cast<oType>(mProd) ) );
|
|
||||||
mProductCreated = false;
|
|
||||||
}
|
|
||||||
std::dynamic_pointer_cast<oType>(mProd)->mOrig.push_back(r);
|
|
||||||
std::dynamic_pointer_cast<oType>(mProd)->mSize *= r->size();
|
|
||||||
std::dynamic_pointer_cast<oType>(mProd)->mEmpty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************
|
|
||||||
* Functions *
|
|
||||||
*****************/
|
|
||||||
|
|
||||||
//std::shared_ptr<DynamicRange> defaultRange(size_t size = 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace MultiArrayHelper
|
namespace MultiArrayHelper
|
||||||
{
|
{
|
||||||
using namespace MultiArrayTools;
|
using namespace MultiArrayTools;
|
||||||
|
|
||||||
template <>
|
template <class EC>
|
||||||
inline void resolveSetRange<DynamicRange>(std::shared_ptr<DynamicRange>& rp,
|
inline void resolveSetRange(std::shared_ptr<DynamicRange<EC>>& rp,
|
||||||
const std::vector<std::shared_ptr<RangeBase> >& orig,
|
const std::vector<std::shared_ptr<RangeBase> >& orig,
|
||||||
size_t origpos, size_t size)
|
size_t origpos, size_t size)
|
||||||
{
|
{
|
||||||
DynamicRangeFactory arf;
|
DynamicRangeFactory<EC> arf;
|
||||||
for(size_t op = origpos; op != origpos + size; ++op){
|
for(size_t op = origpos; op != origpos + size; ++op){
|
||||||
//VCHECK(op);
|
//VCHECK(op);
|
||||||
arf.append(orig[op]);
|
arf.append(orig[op]);
|
||||||
}
|
}
|
||||||
rp = std::dynamic_pointer_cast<DynamicRange>( arf.create() );
|
rp = std::dynamic_pointer_cast<DynamicRange<EC>>( arf.create() );
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <class EC>
|
||||||
inline void setRangeToVec<DynamicRange>(std::vector<std::shared_ptr<RangeBase> >& v,
|
inline void setRangeToVec(std::vector<std::shared_ptr<RangeBase> >& v,
|
||||||
std::shared_ptr<DynamicRange> r)
|
std::shared_ptr<DynamicRange<EC>> r)
|
||||||
{
|
{
|
||||||
if(not r->isEmpty()){
|
if(not r->isEmpty()){
|
||||||
for(size_t i = r->dim(); i != 0; --i){
|
for(size_t i = r->dim(); i != 0; --i){
|
||||||
|
@ -357,8 +330,8 @@ namespace MultiArrayHelper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <class EC>
|
||||||
inline size_t getStepSize<DynamicIndex>(const DynamicIndex& ii, std::intptr_t j)
|
inline size_t getStepSize(const DynamicIndex<EC>& ii, std::intptr_t j)
|
||||||
{
|
{
|
||||||
size_t ss = 0;
|
size_t ss = 0;
|
||||||
size_t sx = 1;
|
size_t sx = 1;
|
||||||
|
@ -374,79 +347,6 @@ namespace MultiArrayHelper
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MultiArrayTools
|
#include "dynamic_range.cc.h"
|
||||||
{
|
|
||||||
/***********************
|
|
||||||
* DynamicRange *
|
|
||||||
***********************/
|
|
||||||
|
|
||||||
template <class... RangeTypes>
|
|
||||||
SingleRange<size_t,SpaceType::DYN>::SingleRange(const std::tuple<std::shared_ptr<RangeTypes>...>& origs) :
|
|
||||||
RangeInterface<DynamicIndex>()
|
|
||||||
{
|
|
||||||
RPackNum<sizeof...(RangeTypes)-1>::RangesToVec( origs, mOrig );
|
|
||||||
mSize = RPackNum<sizeof...(RangeTypes)-1>::getSize( origs );
|
|
||||||
if(sizeof...(RangeTypes)){
|
|
||||||
mEmpty = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... RangeTypes>
|
|
||||||
SingleRange<size_t,SpaceType::DYN>::SingleRange(std::shared_ptr<RangeTypes>... origs) :
|
|
||||||
RangeInterface<DynamicIndex>()
|
|
||||||
{
|
|
||||||
auto rst = std::make_tuple(origs...);
|
|
||||||
RPackNum<sizeof...(RangeTypes)-1>::RangesToVec( rst, mOrig );
|
|
||||||
mSize = RPackNum<sizeof...(RangeTypes)-1>::getSize( rst );
|
|
||||||
if(sizeof...(RangeTypes)){
|
|
||||||
mEmpty = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Range>
|
|
||||||
std::shared_ptr<Range> SingleRange<size_t,SpaceType::DYN>::fullsub(size_t num) const
|
|
||||||
{
|
|
||||||
return std::dynamic_pointer_cast<Range>( mOrig.at(num) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Ranges>
|
|
||||||
std::shared_ptr<MultiRange<Ranges...> > SingleRange<size_t,SpaceType::DYN>::scast(SIZET<Ranges>... sizes) const
|
|
||||||
{
|
|
||||||
std::tuple<std::shared_ptr<Ranges>...> rtp;
|
|
||||||
RPackNum<sizeof...(Ranges)-1>::resolveRangeType(mOrig, rtp, 0, sizes...);
|
|
||||||
MultiRangeFactory<Ranges...> mrf(rtp);
|
|
||||||
return std::dynamic_pointer_cast<MultiRange<Ranges...> >( mrf.create() );
|
|
||||||
}
|
|
||||||
|
|
||||||
inline DynamicalExpression DynamicIndex::mkFor(size_t i, size_t step,
|
|
||||||
DynamicalExpression ex, bool hidden) const
|
|
||||||
{
|
|
||||||
if(i != 0){
|
|
||||||
auto& ii = *mIVec[i].first;
|
|
||||||
return mkFor(i-1, step, hidden ? ii.iforh(step, ex) : ii.ifor(step, ex));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
auto& ii = *mIVec[0].first;
|
|
||||||
return hidden ? ii.iforh(step, ex) : ii.ifor(step, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Expr>
|
|
||||||
auto DynamicIndex::ifor(size_t step, Expr ex) const
|
|
||||||
-> DynamicalExpression
|
|
||||||
{
|
|
||||||
DynamicalExpression expr(std::make_shared<Expr>(ex));
|
|
||||||
return mkFor(mIVec.size()-1, step, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Expr>
|
|
||||||
auto DynamicIndex::iforh(size_t step, Expr ex) const
|
|
||||||
-> DynamicalExpression
|
|
||||||
{
|
|
||||||
DynamicalExpression expr(std::make_shared<Expr>(ex));
|
|
||||||
return mkFor(mIVec.size()-1, step, expr, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -79,13 +79,16 @@ namespace MultiArrayTools
|
||||||
//class AnonymousRange;
|
//class AnonymousRange;
|
||||||
|
|
||||||
// dynamic_range.h
|
// dynamic_range.h
|
||||||
|
template <class EC>
|
||||||
class DynamicIndex;
|
class DynamicIndex;
|
||||||
|
|
||||||
// dynamic_range.h
|
// dynamic_range.h
|
||||||
|
template <class EC>
|
||||||
class DynamicRangeFactory;
|
class DynamicRangeFactory;
|
||||||
|
|
||||||
// dynamic_range.h
|
// dynamic_range.h
|
||||||
//class DynamicRange;
|
template <class EC>
|
||||||
|
class DynamicRange;
|
||||||
|
|
||||||
// value_range.h
|
// value_range.h
|
||||||
template <typename U>
|
template <typename U>
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
//#ifndef __rheader_h__
|
//#ifndef __rheader_h__
|
||||||
//#define __rheader_h__
|
//#define __rheader_h__
|
||||||
|
|
||||||
|
#include "dynamic_range.h"
|
||||||
#include "rpheader.h"
|
#include "rpheader.h"
|
||||||
#include "anonymous_range.h"
|
#include "anonymous_range.h"
|
||||||
#include "dynamic_range.h"
|
|
||||||
#include "value_range.h"
|
#include "value_range.h"
|
||||||
|
|
||||||
//#endif
|
//#endif
|
||||||
|
|
256
src/include/slice.cc.h
Normal file
256
src/include/slice.cc.h
Normal file
|
@ -0,0 +1,256 @@
|
||||||
|
|
||||||
|
#include "slice.h"
|
||||||
|
|
||||||
|
namespace MultiArrayTools
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************
|
||||||
|
* ConstSlice *
|
||||||
|
*******************/
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
void ConstSlice<T,SRanges...>::format(const std::array<size_t,sizeof...(SRanges)+1>& blocks)
|
||||||
|
{
|
||||||
|
MAB::mProtoI->format(blocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
ConstSlice<T,SRanges...>::ConstSlice(const std::shared_ptr<SRanges>&... ranges, const T* data) :
|
||||||
|
MultiArrayBase<T,SRanges...>(ranges...),
|
||||||
|
mData(data)
|
||||||
|
{
|
||||||
|
MAB::mInit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
ConstSlice<T,SRanges...>::ConstSlice(const MultiArrayBase<T,AnonymousRange>& ma, SIZET<SRanges>... sizes) :
|
||||||
|
MultiArrayBase<T,SRanges...>
|
||||||
|
( ma.range()->template get<0>().template scast<SRanges...>(sizes...)->space() ),
|
||||||
|
mData( ma.data() )
|
||||||
|
{
|
||||||
|
MAB::mInit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
const T& ConstSlice<T,SRanges...>::operator[](const IType& i) const
|
||||||
|
{
|
||||||
|
//assert(i.sliceMode()); // -> compare objects !!!!!
|
||||||
|
assert(i.container() == reinterpret_cast<std::intptr_t>(this));
|
||||||
|
return mData[ i.pos() ];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
const T& ConstSlice<T,SRanges...>::at(const typename IType::MetaType& meta) const
|
||||||
|
{
|
||||||
|
//auto x = begin().at(meta);
|
||||||
|
//VCHECK(x.pos());
|
||||||
|
return mData[ begin().at(meta).pos() ];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
const T* ConstSlice<T,SRanges...>::data() const
|
||||||
|
{
|
||||||
|
return mData;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
bool ConstSlice<T,SRanges...>::isSlice() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
auto ConstSlice<T,SRanges...>::begin() const -> ConstSlice<T,SRanges...>::IType
|
||||||
|
{
|
||||||
|
IType i(*MAB::mProtoI);
|
||||||
|
i = 0;
|
||||||
|
//i = mStartPos;
|
||||||
|
return i.setData(data());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
auto ConstSlice<T,SRanges...>::end() const -> ConstSlice<T,SRanges...>::IType
|
||||||
|
{
|
||||||
|
IType i(*MAB::mProtoI);
|
||||||
|
i = i.max(); // CHECK !!!
|
||||||
|
//i = std::get<sizeof...(SRanges)>(mBlockSizes);
|
||||||
|
return i.setData(data());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > ConstSlice<T,SRanges...>::anonymous(bool slice) const
|
||||||
|
{
|
||||||
|
assert(0); // think about carefully!!!!
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
auto ConstSlice<T,SRanges...>::define(const std::shared_ptr<typename SRanges::IndexType>&... inds)
|
||||||
|
-> ConstSliceDef<T,SRanges...>
|
||||||
|
{
|
||||||
|
return ConstSliceDef<T,SRanges...>(*this, inds...);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************
|
||||||
|
* Slice *
|
||||||
|
**************/
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
void Slice<T,SRanges...>::format(const std::array<size_t,sizeof...(SRanges)+1>& blocks)
|
||||||
|
{
|
||||||
|
MAB::mProtoI->format(blocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
Slice<T,SRanges...>::Slice(const std::shared_ptr<SRanges>&... ranges, T* data) :
|
||||||
|
MutableMultiArrayBase<T,SRanges...>(ranges...),
|
||||||
|
mData(data) {}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
const T& Slice<T,SRanges...>::operator[](const IType& i) const
|
||||||
|
{
|
||||||
|
//assert(i.sliceMode()); // -> compare objects !!!!!
|
||||||
|
assert(i.container() == reinterpret_cast<std::intptr_t>(this));
|
||||||
|
return mData[ i.pos() ];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
T& Slice<T,SRanges...>::operator[](const IType& i)
|
||||||
|
{
|
||||||
|
//assert(i.sliceMode());
|
||||||
|
assert(i.container() == reinterpret_cast<std::intptr_t>(this));
|
||||||
|
return mData[ i.pos() ];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
const T& Slice<T,SRanges...>::at(const typename IType::MetaType& meta) const
|
||||||
|
{
|
||||||
|
//auto x = begin().at(meta);
|
||||||
|
//VCHECK(x.pos());
|
||||||
|
return mData[ begin().at(meta).pos() ];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
T& Slice<T,SRanges...>::at(const typename IType::MetaType& meta)
|
||||||
|
{
|
||||||
|
//auto x = begin().at(meta);
|
||||||
|
//VCHECK(x.pos());
|
||||||
|
return mData[ begin().at(meta).pos() ];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
const T* Slice<T,SRanges...>::data() const
|
||||||
|
{
|
||||||
|
return mData;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
T* Slice<T,SRanges...>::data()
|
||||||
|
{
|
||||||
|
return mData;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
bool Slice<T,SRanges...>::isSlice() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
auto Slice<T,SRanges...>::begin() const -> Slice<T,SRanges...>::IType
|
||||||
|
{
|
||||||
|
IType i(*MAB::mProtoI);
|
||||||
|
i = 0;
|
||||||
|
//i = mStartPos;
|
||||||
|
return i.setData(data());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
auto Slice<T,SRanges...>::end() const -> Slice<T,SRanges...>::IType
|
||||||
|
{
|
||||||
|
IType i(*MAB::mProtoI);
|
||||||
|
i = i.max(); // CHECK !!!
|
||||||
|
//i = std::get<sizeof...(SRanges)>(mBlockSizes);
|
||||||
|
return i.setData(data());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > Slice<T,SRanges...>::anonymous(bool slice) const
|
||||||
|
{
|
||||||
|
assert(0); // think about carefully!!!!
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > Slice<T,SRanges...>::anonymousMove()
|
||||||
|
{
|
||||||
|
assert(0); // think about carefully!!!!
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
auto Slice<T,SRanges...>::define(const std::shared_ptr<typename SRanges::IndexType>&... inds)
|
||||||
|
-> SliceDef<T,SRanges...>
|
||||||
|
{
|
||||||
|
return SliceDef<T,SRanges...>(*this, inds...);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
SliceDef<T,SRanges...>::SliceDef(Slice<T,SRanges...>& sl,
|
||||||
|
const std::shared_ptr<typename SRanges::IndexType>&... inds) :
|
||||||
|
mIndex(sl.begin()),
|
||||||
|
mSl(sl)
|
||||||
|
{
|
||||||
|
mIndex(inds...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
template <class... ORanges>
|
||||||
|
SliceDef<T,SRanges...>& SliceDef<T,SRanges...>::operator=(const OperationRoot<T,ORanges...>& op)
|
||||||
|
{
|
||||||
|
std::array<size_t,sizeof...(SRanges)+1> blocks;
|
||||||
|
PackNum<sizeof...(SRanges)-1>::
|
||||||
|
template mkSliceBlocks<T,OperationRoot<T,ORanges...>,SRanges...>(blocks, mIndex, op);
|
||||||
|
mSl.format(blocks);
|
||||||
|
mSl.mData = op.data();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
ConstSliceDef<T,SRanges...>::ConstSliceDef(ConstSlice<T,SRanges...>& sl,
|
||||||
|
const std::shared_ptr<typename SRanges::IndexType>&... inds) :
|
||||||
|
mIndex(sl.begin()),
|
||||||
|
mSl(sl)
|
||||||
|
{
|
||||||
|
mIndex(inds...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
template <class... ORanges>
|
||||||
|
ConstSliceDef<T,SRanges...>& ConstSliceDef<T,SRanges...>::operator=(const ConstOperationRoot<T,ORanges...>& op)
|
||||||
|
{
|
||||||
|
std::array<size_t,sizeof...(SRanges)+1> blocks;
|
||||||
|
PackNum<sizeof...(SRanges)-1>::
|
||||||
|
template mkSliceBlocks<T,ConstOperationRoot<T,ORanges...>,SRanges...>(blocks, mIndex, op);
|
||||||
|
mSl.format(blocks);
|
||||||
|
mSl.mData = op.data();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class... SRanges>
|
||||||
|
template <class... ORanges>
|
||||||
|
ConstSliceDef<T,SRanges...>& ConstSliceDef<T,SRanges...>::operator=(const OperationRoot<T,ORanges...>& op)
|
||||||
|
{
|
||||||
|
std::array<size_t,sizeof...(SRanges)+1> blocks;
|
||||||
|
PackNum<sizeof...(SRanges)-1>::
|
||||||
|
template mkSliceBlocks<T,OperationRoot<T,ORanges...>,SRanges...>(blocks, mIndex, op);
|
||||||
|
mSl.format(blocks);
|
||||||
|
mSl.mData = op.data();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // end namespace MultiArrayTools
|
||||||
|
|
|
@ -179,257 +179,5 @@ namespace MultiArrayTools
|
||||||
* --- TEMPLATE CODE --- *
|
* --- TEMPLATE CODE --- *
|
||||||
* ========================= */
|
* ========================= */
|
||||||
|
|
||||||
namespace MultiArrayTools
|
|
||||||
{
|
|
||||||
|
|
||||||
/*******************
|
|
||||||
* ConstSlice *
|
|
||||||
*******************/
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
void ConstSlice<T,SRanges...>::format(const std::array<size_t,sizeof...(SRanges)+1>& blocks)
|
|
||||||
{
|
|
||||||
MAB::mProtoI->format(blocks);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
ConstSlice<T,SRanges...>::ConstSlice(const std::shared_ptr<SRanges>&... ranges, const T* data) :
|
|
||||||
MultiArrayBase<T,SRanges...>(ranges...),
|
|
||||||
mData(data)
|
|
||||||
{
|
|
||||||
MAB::mInit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
ConstSlice<T,SRanges...>::ConstSlice(const MultiArrayBase<T,AnonymousRange>& ma, SIZET<SRanges>... sizes) :
|
|
||||||
MultiArrayBase<T,SRanges...>
|
|
||||||
( ma.range()->template get<0>().template scast<SRanges...>(sizes...)->space() ),
|
|
||||||
mData( ma.data() )
|
|
||||||
{
|
|
||||||
MAB::mInit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
const T& ConstSlice<T,SRanges...>::operator[](const IType& i) const
|
|
||||||
{
|
|
||||||
//assert(i.sliceMode()); // -> compare objects !!!!!
|
|
||||||
assert(i.container() == reinterpret_cast<std::intptr_t>(this));
|
|
||||||
return mData[ i.pos() ];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
const T& ConstSlice<T,SRanges...>::at(const typename IType::MetaType& meta) const
|
|
||||||
{
|
|
||||||
//auto x = begin().at(meta);
|
|
||||||
//VCHECK(x.pos());
|
|
||||||
return mData[ begin().at(meta).pos() ];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
const T* ConstSlice<T,SRanges...>::data() const
|
|
||||||
{
|
|
||||||
return mData;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
bool ConstSlice<T,SRanges...>::isSlice() const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
auto ConstSlice<T,SRanges...>::begin() const -> ConstSlice<T,SRanges...>::IType
|
|
||||||
{
|
|
||||||
IType i(*MAB::mProtoI);
|
|
||||||
i = 0;
|
|
||||||
//i = mStartPos;
|
|
||||||
return i.setData(data());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
auto ConstSlice<T,SRanges...>::end() const -> ConstSlice<T,SRanges...>::IType
|
|
||||||
{
|
|
||||||
IType i(*MAB::mProtoI);
|
|
||||||
i = i.max(); // CHECK !!!
|
|
||||||
//i = std::get<sizeof...(SRanges)>(mBlockSizes);
|
|
||||||
return i.setData(data());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > ConstSlice<T,SRanges...>::anonymous(bool slice) const
|
|
||||||
{
|
|
||||||
assert(0); // think about carefully!!!!
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
auto ConstSlice<T,SRanges...>::define(const std::shared_ptr<typename SRanges::IndexType>&... inds)
|
|
||||||
-> ConstSliceDef<T,SRanges...>
|
|
||||||
{
|
|
||||||
return ConstSliceDef<T,SRanges...>(*this, inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************
|
|
||||||
* Slice *
|
|
||||||
**************/
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
void Slice<T,SRanges...>::format(const std::array<size_t,sizeof...(SRanges)+1>& blocks)
|
|
||||||
{
|
|
||||||
MAB::mProtoI->format(blocks);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
Slice<T,SRanges...>::Slice(const std::shared_ptr<SRanges>&... ranges, T* data) :
|
|
||||||
MutableMultiArrayBase<T,SRanges...>(ranges...),
|
|
||||||
mData(data) {}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
const T& Slice<T,SRanges...>::operator[](const IType& i) const
|
|
||||||
{
|
|
||||||
//assert(i.sliceMode()); // -> compare objects !!!!!
|
|
||||||
assert(i.container() == reinterpret_cast<std::intptr_t>(this));
|
|
||||||
return mData[ i.pos() ];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
T& Slice<T,SRanges...>::operator[](const IType& i)
|
|
||||||
{
|
|
||||||
//assert(i.sliceMode());
|
|
||||||
assert(i.container() == reinterpret_cast<std::intptr_t>(this));
|
|
||||||
return mData[ i.pos() ];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
const T& Slice<T,SRanges...>::at(const typename IType::MetaType& meta) const
|
|
||||||
{
|
|
||||||
//auto x = begin().at(meta);
|
|
||||||
//VCHECK(x.pos());
|
|
||||||
return mData[ begin().at(meta).pos() ];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
T& Slice<T,SRanges...>::at(const typename IType::MetaType& meta)
|
|
||||||
{
|
|
||||||
//auto x = begin().at(meta);
|
|
||||||
//VCHECK(x.pos());
|
|
||||||
return mData[ begin().at(meta).pos() ];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
const T* Slice<T,SRanges...>::data() const
|
|
||||||
{
|
|
||||||
return mData;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
T* Slice<T,SRanges...>::data()
|
|
||||||
{
|
|
||||||
return mData;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
bool Slice<T,SRanges...>::isSlice() const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
auto Slice<T,SRanges...>::begin() const -> Slice<T,SRanges...>::IType
|
|
||||||
{
|
|
||||||
IType i(*MAB::mProtoI);
|
|
||||||
i = 0;
|
|
||||||
//i = mStartPos;
|
|
||||||
return i.setData(data());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
auto Slice<T,SRanges...>::end() const -> Slice<T,SRanges...>::IType
|
|
||||||
{
|
|
||||||
IType i(*MAB::mProtoI);
|
|
||||||
i = i.max(); // CHECK !!!
|
|
||||||
//i = std::get<sizeof...(SRanges)>(mBlockSizes);
|
|
||||||
return i.setData(data());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > Slice<T,SRanges...>::anonymous(bool slice) const
|
|
||||||
{
|
|
||||||
assert(0); // think about carefully!!!!
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > Slice<T,SRanges...>::anonymousMove()
|
|
||||||
{
|
|
||||||
assert(0); // think about carefully!!!!
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
auto Slice<T,SRanges...>::define(const std::shared_ptr<typename SRanges::IndexType>&... inds)
|
|
||||||
-> SliceDef<T,SRanges...>
|
|
||||||
{
|
|
||||||
return SliceDef<T,SRanges...>(*this, inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
SliceDef<T,SRanges...>::SliceDef(Slice<T,SRanges...>& sl,
|
|
||||||
const std::shared_ptr<typename SRanges::IndexType>&... inds) :
|
|
||||||
mIndex(sl.begin()),
|
|
||||||
mSl(sl)
|
|
||||||
{
|
|
||||||
mIndex(inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
template <class... ORanges>
|
|
||||||
SliceDef<T,SRanges...>& SliceDef<T,SRanges...>::operator=(const OperationRoot<T,ORanges...>& op)
|
|
||||||
{
|
|
||||||
std::array<size_t,sizeof...(SRanges)+1> blocks;
|
|
||||||
PackNum<sizeof...(SRanges)-1>::
|
|
||||||
template mkSliceBlocks<T,OperationRoot<T,ORanges...>,SRanges...>(blocks, mIndex, op);
|
|
||||||
mSl.format(blocks);
|
|
||||||
mSl.mData = op.data();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
ConstSliceDef<T,SRanges...>::ConstSliceDef(ConstSlice<T,SRanges...>& sl,
|
|
||||||
const std::shared_ptr<typename SRanges::IndexType>&... inds) :
|
|
||||||
mIndex(sl.begin()),
|
|
||||||
mSl(sl)
|
|
||||||
{
|
|
||||||
mIndex(inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
template <class... ORanges>
|
|
||||||
ConstSliceDef<T,SRanges...>& ConstSliceDef<T,SRanges...>::operator=(const ConstOperationRoot<T,ORanges...>& op)
|
|
||||||
{
|
|
||||||
std::array<size_t,sizeof...(SRanges)+1> blocks;
|
|
||||||
PackNum<sizeof...(SRanges)-1>::
|
|
||||||
template mkSliceBlocks<T,ConstOperationRoot<T,ORanges...>,SRanges...>(blocks, mIndex, op);
|
|
||||||
mSl.format(blocks);
|
|
||||||
mSl.mData = op.data();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... SRanges>
|
|
||||||
template <class... ORanges>
|
|
||||||
ConstSliceDef<T,SRanges...>& ConstSliceDef<T,SRanges...>::operator=(const OperationRoot<T,ORanges...>& op)
|
|
||||||
{
|
|
||||||
std::array<size_t,sizeof...(SRanges)+1> blocks;
|
|
||||||
PackNum<sizeof...(SRanges)-1>::
|
|
||||||
template mkSliceBlocks<T,OperationRoot<T,ORanges...>,SRanges...>(blocks, mIndex, op);
|
|
||||||
mSl.format(blocks);
|
|
||||||
mSl.mData = op.data();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // end namespace MultiArrayTools
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -84,42 +84,6 @@ namespace MultiArrayHelper
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Expr>
|
|
||||||
class ExpressionHolder : public ExpressionBase
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
ExpressionHolder() = default;
|
|
||||||
|
|
||||||
Expr mExpr;
|
|
||||||
typedef decltype(mExpr.rootSteps()) ExtType;
|
|
||||||
ExtType mExt;
|
|
||||||
|
|
||||||
mutable ExtType mRootSteps;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef ExpressionBase EB;
|
|
||||||
|
|
||||||
static constexpr size_t LAYER = Expr::LAYER + 1;
|
|
||||||
static constexpr size_t SIZE = Expr::SIZE;
|
|
||||||
|
|
||||||
ExpressionHolder(const ExpressionHolder& in) = default;
|
|
||||||
ExpressionHolder(ExpressionHolder&& in) = default;
|
|
||||||
ExpressionHolder& operator=(const ExpressionHolder& in) = default;
|
|
||||||
ExpressionHolder& operator=(ExpressionHolder&& in) = default;
|
|
||||||
|
|
||||||
ExpressionHolder(Expr expr);
|
|
||||||
|
|
||||||
inline void operator()(size_t mlast, DExt last) const override final;
|
|
||||||
inline void operator()(size_t mlast, ExtType last) const;
|
|
||||||
inline void operator()(size_t mlast = 0) const override final;
|
|
||||||
|
|
||||||
DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
|
|
||||||
DExt dExtension() const override final;
|
|
||||||
|
|
||||||
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
|
|
||||||
auto extension() const -> ExtType;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class IndexClass, class Expr>
|
template <class IndexClass, class Expr>
|
||||||
class SingleExpression : public ExpressionBase
|
class SingleExpression : public ExpressionBase
|
||||||
|
@ -218,24 +182,27 @@ namespace MultiArrayHelper
|
||||||
template <>
|
template <>
|
||||||
inline size_t exceptMax<1>(size_t max) { return 1; }
|
inline size_t exceptMax<1>(size_t max) { return 1; }
|
||||||
|
|
||||||
class DynamicalExpression : public ExpressionBase
|
class DynamicExpression : public ExpressionBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
DynamicalExpression() = default;
|
DynamicExpression() = default;
|
||||||
|
|
||||||
std::shared_ptr<ExpressionBase> mNext;
|
std::shared_ptr<ExpressionBase> mNext;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DynamicalExpression(const DynamicalExpression& in) = default;
|
DynamicExpression(const DynamicExpression& in) = default;
|
||||||
DynamicalExpression(DynamicalExpression&& in) = default;
|
DynamicExpression(DynamicExpression&& in) = default;
|
||||||
DynamicalExpression& operator=(const DynamicalExpression& in) = default;
|
DynamicExpression& operator=(const DynamicExpression& in) = default;
|
||||||
DynamicalExpression& operator=(DynamicalExpression&& in) = default;
|
DynamicExpression& operator=(DynamicExpression&& in) = default;
|
||||||
|
|
||||||
DynamicalExpression(const std::shared_ptr<ExpressionBase>& next) :
|
DynamicExpression(const std::shared_ptr<ExpressionBase>& next) :
|
||||||
mNext(next)
|
mNext(next)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
template <class Expr>
|
||||||
|
DynamicExpression(Expr ex) : mNext( std::make_shared<Expr>(ex) ) {}
|
||||||
|
|
||||||
inline void operator()(size_t mlast, DExt last) const override final;
|
inline void operator()(size_t mlast, DExt last) const override final;
|
||||||
inline void operator()(size_t mlast = 0) const override final;
|
inline void operator()(size_t mlast = 0) const override final;
|
||||||
|
|
||||||
|
@ -244,6 +211,44 @@ namespace MultiArrayHelper
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class Expr>
|
||||||
|
class ExpressionHolder : public ExpressionBase
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
ExpressionHolder() = default;
|
||||||
|
|
||||||
|
DynamicExpression mExpr;
|
||||||
|
typedef decltype(std::declval<Expr>().rootSteps()) ExtType;
|
||||||
|
ExtType mExt;
|
||||||
|
|
||||||
|
mutable ExtType mRootSteps;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef ExpressionBase EB;
|
||||||
|
|
||||||
|
static constexpr size_t LAYER = Expr::LAYER + 1;
|
||||||
|
static constexpr size_t SIZE = Expr::SIZE;
|
||||||
|
|
||||||
|
ExpressionHolder(const ExpressionHolder& in) = default;
|
||||||
|
ExpressionHolder(ExpressionHolder&& in) = default;
|
||||||
|
ExpressionHolder& operator=(const ExpressionHolder& in) = default;
|
||||||
|
ExpressionHolder& operator=(ExpressionHolder&& in) = default;
|
||||||
|
|
||||||
|
ExpressionHolder(DynamicExpression expr);
|
||||||
|
|
||||||
|
inline void operator()(size_t mlast, DExt last) const override final;
|
||||||
|
inline void operator()(size_t mlast, ExtType last) const;
|
||||||
|
inline void operator()(size_t mlast = 0) const override final;
|
||||||
|
|
||||||
|
DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
|
||||||
|
DExt dExtension() const override final;
|
||||||
|
|
||||||
|
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
|
||||||
|
auto extension() const -> ExtType;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace MultiArrayHelper
|
} // namespace MultiArrayHelper
|
||||||
|
|
||||||
/* ========================= *
|
/* ========================= *
|
||||||
|
@ -429,25 +434,25 @@ namespace MultiArrayHelper
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************
|
/***************************
|
||||||
* DynamicalExpression *
|
* DynamicExpression *
|
||||||
***************************/
|
***************************/
|
||||||
|
|
||||||
inline void DynamicalExpression::operator()(size_t mlast, DExt last) const
|
inline void DynamicExpression::operator()(size_t mlast, DExt last) const
|
||||||
{
|
{
|
||||||
(*mNext)(mlast,last);
|
(*mNext)(mlast,last);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void DynamicalExpression::operator()(size_t mlast) const
|
inline void DynamicExpression::operator()(size_t mlast) const
|
||||||
{
|
{
|
||||||
(*mNext)(mlast);
|
(*mNext)(mlast);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline DExt DynamicalExpression::dRootSteps(std::intptr_t iPtrNum) const
|
inline DExt DynamicExpression::dRootSteps(std::intptr_t iPtrNum) const
|
||||||
{
|
{
|
||||||
return mNext->dRootSteps(iPtrNum);
|
return mNext->dRootSteps(iPtrNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline DExt DynamicalExpression::dExtension() const
|
inline DExt DynamicExpression::dExtension() const
|
||||||
{
|
{
|
||||||
return mNext->dExtension();
|
return mNext->dExtension();
|
||||||
}
|
}
|
||||||
|
@ -457,7 +462,7 @@ namespace MultiArrayHelper
|
||||||
************************/
|
************************/
|
||||||
|
|
||||||
template <class Expr>
|
template <class Expr>
|
||||||
ExpressionHolder<Expr>::ExpressionHolder(Expr expr) : mExpr(expr) {}
|
ExpressionHolder<Expr>::ExpressionHolder(DynamicExpression expr) : mExpr(expr) {}
|
||||||
|
|
||||||
template <class Expr>
|
template <class Expr>
|
||||||
inline void ExpressionHolder<Expr>::operator()(size_t mlast, DExt last) const
|
inline void ExpressionHolder<Expr>::operator()(size_t mlast, DExt last) const
|
||||||
|
@ -468,7 +473,10 @@ namespace MultiArrayHelper
|
||||||
template <class Expr>
|
template <class Expr>
|
||||||
inline void ExpressionHolder<Expr>::operator()(size_t mlast, ExtType last) const
|
inline void ExpressionHolder<Expr>::operator()(size_t mlast, ExtType last) const
|
||||||
{
|
{
|
||||||
mExpr(mlast,last);
|
mExpr(mlast,
|
||||||
|
std::make_pair<size_t const*,size_t>
|
||||||
|
(reinterpret_cast<size_t const*>(&last),
|
||||||
|
sizeof(ExtType)/sizeof(size_t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Expr>
|
template <class Expr>
|
||||||
|
@ -493,14 +501,14 @@ namespace MultiArrayHelper
|
||||||
auto ExpressionHolder<Expr>::rootSteps(std::intptr_t iPtrNum) const
|
auto ExpressionHolder<Expr>::rootSteps(std::intptr_t iPtrNum) const
|
||||||
-> ExtType
|
-> ExtType
|
||||||
{
|
{
|
||||||
return mExpr.rootSteps(iPtrNum);
|
return *reinterpret_cast<ExtType*>( mExpr.dRootSteps(iPtrNum).first );
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Expr>
|
template <class Expr>
|
||||||
auto ExpressionHolder<Expr>::extension() const
|
auto ExpressionHolder<Expr>::extension() const
|
||||||
-> ExtType
|
-> ExtType
|
||||||
{
|
{
|
||||||
return mExpr.extension();
|
return *reinterpret_cast<ExtType*>( mExpr.dExtension().first );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
set(libmultiarray_a_SOURCES
|
set(libmultiarray_a_SOURCES
|
||||||
${CMAKE_SOURCE_DIR}/src/lib/ranges/range_base.cc
|
${CMAKE_SOURCE_DIR}/src/lib/ranges/range_base.cc
|
||||||
${CMAKE_SOURCE_DIR}/src/lib/ranges/anonymous_range.cc
|
${CMAKE_SOURCE_DIR}/src/lib/ranges/anonymous_range.cc
|
||||||
${CMAKE_SOURCE_DIR}/src/lib/ranges/dynamic_range.cc
|
${CMAKE_SOURCE_DIR}/src/lib/ranges/dynamic_meta.cc
|
||||||
${CMAKE_SOURCE_DIR}/src/lib/ranges/multi_range_factory_product_map.cc
|
${CMAKE_SOURCE_DIR}/src/lib/ranges/multi_range_factory_product_map.cc
|
||||||
${CMAKE_SOURCE_DIR}/src/lib/map_range_factory_product_map.cc
|
${CMAKE_SOURCE_DIR}/src/lib/map_range_factory_product_map.cc
|
||||||
)
|
)
|
||||||
|
|
47
src/lib/ranges/dynamic_meta.cc
Normal file
47
src/lib/ranges/dynamic_meta.cc
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <vector>
|
||||||
|
#include "ranges/dynamic_meta.h"
|
||||||
|
|
||||||
|
namespace MultiArrayTools
|
||||||
|
{
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DynamicMetaT *
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
bool DynamicMetaT::operator==(const DynamicMetaT& in) const
|
||||||
|
{
|
||||||
|
if(in.size() != mMeta.size()) { return false; }
|
||||||
|
for(size_t i = 0; i != mMeta.size(); ++i){
|
||||||
|
if(in[i].second != mMeta[i].second) { return false; }
|
||||||
|
for(size_t j = 0; j != mMeta[i].second; ++j){
|
||||||
|
if(in[i].first[j] != mMeta[i].first[j]) { return false; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DynamicMetaT::operator!=(const DynamicMetaT& in) const
|
||||||
|
{
|
||||||
|
return not operator==(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t DynamicMetaT::size() const
|
||||||
|
{
|
||||||
|
return mMeta.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicMetaElem& DynamicMetaT::operator[](size_t pos)
|
||||||
|
{
|
||||||
|
return mMeta[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
const DynamicMetaElem& DynamicMetaT::operator[](size_t pos) const
|
||||||
|
{
|
||||||
|
return mMeta[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace MultiArrayTools
|
|
@ -1,363 +0,0 @@
|
||||||
|
|
||||||
#include "ranges/dynamic_range.h"
|
|
||||||
#include "ranges/dynamic_meta.h"
|
|
||||||
|
|
||||||
namespace MultiArrayTools
|
|
||||||
{
|
|
||||||
/*********************
|
|
||||||
* DynamicMetaT *
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
bool DynamicMetaT::operator==(const DynamicMetaT& in) const
|
|
||||||
{
|
|
||||||
if(in.size() != mMeta.size()) { return false; }
|
|
||||||
for(size_t i = 0; i != mMeta.size(); ++i){
|
|
||||||
if(in[i].second != mMeta[i].second) { return false; }
|
|
||||||
for(size_t j = 0; j != mMeta[i].second; ++j){
|
|
||||||
if(in[i].first[j] != mMeta[i].first[j]) { return false; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DynamicMetaT::operator!=(const DynamicMetaT& in) const
|
|
||||||
{
|
|
||||||
return not operator==(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t DynamicMetaT::size() const
|
|
||||||
{
|
|
||||||
return mMeta.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicMetaElem& DynamicMetaT::operator[](size_t pos)
|
|
||||||
{
|
|
||||||
return mMeta[pos];
|
|
||||||
}
|
|
||||||
|
|
||||||
const DynamicMetaElem& DynamicMetaT::operator[](size_t pos) const
|
|
||||||
{
|
|
||||||
return mMeta[pos];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DynamicIndex *
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
|
|
||||||
DynamicIndex::DynamicIndex(const std::shared_ptr<DynamicRange >& range) :
|
|
||||||
IndexInterface<DynamicIndex,MetaType>(range, 0)//,
|
|
||||||
//mExplicitRangePtr(std::dynamic_pointer_cast<RangeType>(IB::mRangePtr)),
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
IndexType DynamicIndex::type() const
|
|
||||||
{
|
|
||||||
return IndexType::SINGLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DynamicIndex& DynamicIndex::operator=(size_t pos)
|
|
||||||
{
|
|
||||||
IB::mPos = pos;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicIndex& DynamicIndex::operator++()
|
|
||||||
{
|
|
||||||
size_t ipos = mIVec.size()-1;
|
|
||||||
auto& ii = mIVec[ipos].first;
|
|
||||||
auto& jj = mIVec[ipos-1].first;
|
|
||||||
while(ii->pos() == ii->max()-1 and ipos != 0) {
|
|
||||||
(*ii) = 0;
|
|
||||||
++(*jj);
|
|
||||||
--ipos;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicIndex& DynamicIndex::operator--()
|
|
||||||
{
|
|
||||||
size_t ipos = mIVec.size()-1;
|
|
||||||
auto& ii = mIVec[ipos].first;
|
|
||||||
auto& jj = mIVec[ipos-1].first;
|
|
||||||
while(ii->pos() == 0 and ipos != 0) {
|
|
||||||
(*ii) = ii->max()-1;
|
|
||||||
--(*jj);
|
|
||||||
--ipos;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicIndex& DynamicIndex::operator()(const IVecT& ivec)
|
|
||||||
{
|
|
||||||
mIVec = ivec;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DynamicIndex::pp(std::intptr_t idxPtrNum)
|
|
||||||
{
|
|
||||||
++(*this);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int DynamicIndex::mm(std::intptr_t idxPtrNum)
|
|
||||||
{
|
|
||||||
--(*this);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string DynamicIndex::stringMeta() const
|
|
||||||
{
|
|
||||||
return std::dynamic_pointer_cast<DynamicRange const>( IB::mRangePtr )->stringMeta(IB::mPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DynamicIndex::MetaType DynamicIndex::meta() const
|
|
||||||
{
|
|
||||||
return std::dynamic_pointer_cast<DynamicRange const>( IB::mRangePtr )->get(IB::mPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const DynamicIndex::MetaType* DynamicIndex::metaPtr() const
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
bool DynamicIndex::isMeta(const MetaType& metaPos) const
|
|
||||||
{
|
|
||||||
return mExplicitRangePtr->isMeta(metaPos);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
DynamicIndex& DynamicIndex::at(const MetaType& metaPos)
|
|
||||||
{
|
|
||||||
(*this) = std::dynamic_pointer_cast<DynamicRange const>( IB::mRangePtr )->getMeta( metaPos );
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t DynamicIndex::posAt(const MetaType& metaPos) const
|
|
||||||
{
|
|
||||||
return std::dynamic_pointer_cast<DynamicRange const>( IB::mRangePtr )->getMeta( metaPos );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t DynamicIndex::dim() const // = 1
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool DynamicIndex::last() const
|
|
||||||
{
|
|
||||||
return IB::mPos == IB::mMax - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool DynamicIndex::first() const
|
|
||||||
{
|
|
||||||
return IB::mPos == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const IndexW& DynamicIndex::get(size_t n) const
|
|
||||||
{
|
|
||||||
return *mIVec[n].first;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<typename DynamicIndex::RangeType> DynamicIndex::range()
|
|
||||||
{
|
|
||||||
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <size_t N>
|
|
||||||
void DynamicIndex::getPtr() {}
|
|
||||||
|
|
||||||
|
|
||||||
size_t DynamicIndex::getStepSize(size_t n) const
|
|
||||||
{
|
|
||||||
return mIVec[n].second;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string DynamicIndex::id() const
|
|
||||||
{
|
|
||||||
return std::string("dyn") + std::to_string(IB::mId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DynamicIndex::print(size_t offset)
|
|
||||||
{
|
|
||||||
if(offset == 0){
|
|
||||||
std::cout << " === " << std::endl;
|
|
||||||
}
|
|
||||||
for(size_t j = 0; j != offset; ++j) { std::cout << "\t"; }
|
|
||||||
std::cout << id() << "[" << reinterpret_cast<std::intptr_t>(this)
|
|
||||||
<< "](" << IB::mRangePtr << "): " /*<< meta().first*/ << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************
|
|
||||||
* DynamicRangeFactory *
|
|
||||||
******************************/
|
|
||||||
|
|
||||||
DynamicRangeFactory::DynamicRangeFactory()
|
|
||||||
{
|
|
||||||
mProd = std::shared_ptr<oType>( new DynamicRange() );
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<std::shared_ptr<RangeBase>,std::vector<std::intptr_t> > DynamicRangeFactory::mAleadyCreated;
|
|
||||||
|
|
||||||
std::shared_ptr<RangeBase> DynamicRangeFactory::checkIfCreated(const std::vector<std::shared_ptr<RangeBase> >& pvec)
|
|
||||||
{
|
|
||||||
std::shared_ptr<RangeBase> out;
|
|
||||||
bool check = false;
|
|
||||||
for(auto& x: mAleadyCreated){
|
|
||||||
if(x.second.size() == pvec.size()){
|
|
||||||
check = true;
|
|
||||||
for(size_t i = 0; i != x.second.size(); ++i){
|
|
||||||
if(x.second[i] != reinterpret_cast<std::intptr_t>( pvec[i].get() ) ){
|
|
||||||
check = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(check == true){
|
|
||||||
out = x.first;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(not check){
|
|
||||||
std::vector<std::intptr_t> app(pvec.size());
|
|
||||||
for(size_t i = 0; i != app.size(); ++i){
|
|
||||||
app[i] = reinterpret_cast<std::intptr_t>( pvec[i].get() );
|
|
||||||
}
|
|
||||||
mAleadyCreated[mProd] = app;
|
|
||||||
out = mProd;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<RangeBase> DynamicRangeFactory::create()
|
|
||||||
{
|
|
||||||
mProd = checkIfCreated(std::dynamic_pointer_cast<DynamicRange>(mProd)->mOrig);
|
|
||||||
setSelf();
|
|
||||||
mProductCreated = true;
|
|
||||||
return mProd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************
|
|
||||||
* DynamicRange *
|
|
||||||
***********************/
|
|
||||||
|
|
||||||
DynamicRange::MetaType DynamicRange::get(size_t pos) const
|
|
||||||
{
|
|
||||||
return MetaType(); // !!!
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t DynamicRange::getMeta(const MetaType& metaPos) const
|
|
||||||
{
|
|
||||||
return 0; // !!!
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t DynamicRange::size() const
|
|
||||||
{
|
|
||||||
return mSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t DynamicRange::dim() const
|
|
||||||
{
|
|
||||||
return mOrig.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
SpaceType DynamicRange::spaceType() const
|
|
||||||
{
|
|
||||||
return SpaceType::DYN;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DynamicRange::isEmpty() const
|
|
||||||
{
|
|
||||||
return mEmpty;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string DynamicRange::stringMeta(size_t pos) const
|
|
||||||
{
|
|
||||||
std::string out = "[ ";
|
|
||||||
//size_t xpos = pos;
|
|
||||||
for(size_t i = mOrig.size(); i != 0; --i) {
|
|
||||||
auto& x = mOrig[i-1];
|
|
||||||
const size_t redpos = pos % x->size();
|
|
||||||
out = ( (i == mOrig.size()) ? out : out + " , " ) + x->stringMeta(redpos);
|
|
||||||
pos -= redpos;
|
|
||||||
pos /= x->size();
|
|
||||||
}
|
|
||||||
out += " ]";
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<char> DynamicRange::data() const
|
|
||||||
{
|
|
||||||
DataHeader h;
|
|
||||||
h.spaceType = static_cast<int>( SpaceType::DYN );
|
|
||||||
h.metaSize = mOrig.size();
|
|
||||||
h.multiple = 1;
|
|
||||||
std::vector<char> out;
|
|
||||||
char* hcp = reinterpret_cast<char*>(&h);
|
|
||||||
out.insert(out.end(), hcp, hcp + sizeof(DataHeader));
|
|
||||||
for(auto& x: mOrig){
|
|
||||||
auto part = x->data();
|
|
||||||
out.insert(out.end(), part.begin(), part.end());
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
typename DynamicRange::IndexType DynamicRange::begin() const
|
|
||||||
{
|
|
||||||
DynamicIndex i
|
|
||||||
(std::dynamic_pointer_cast<DynamicRange>
|
|
||||||
( std::shared_ptr<RangeBase>(RB::mThis) ) );
|
|
||||||
i = 0;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
typename DynamicRange::IndexType DynamicRange::end() const
|
|
||||||
{
|
|
||||||
DynamicIndex i
|
|
||||||
(std::dynamic_pointer_cast<DynamicRange>
|
|
||||||
( std::shared_ptr<RangeBase>(RB::mThis) ) );
|
|
||||||
i = size();
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<RangeBase> DynamicRange::sub(size_t num) const
|
|
||||||
{
|
|
||||||
return mOrig.at(num);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DynamicRange::sreplace(const std::shared_ptr<RangeBase> in, size_t num)
|
|
||||||
{
|
|
||||||
assert(mOrig[num]->size() == in->size());
|
|
||||||
mOrig[num] = in;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************
|
|
||||||
* Functions *
|
|
||||||
*****************/
|
|
||||||
/*
|
|
||||||
std::shared_ptr<DynamicRange> defaultRange(size_t size )
|
|
||||||
{
|
|
||||||
DynamicRangeFactory arf
|
|
||||||
( std::dynamic_pointer_cast<DynamicRange>
|
|
||||||
(DynamicRange::factory().create() ) );
|
|
||||||
return std::dynamic_pointer_cast<DynamicRange>( arf.create() );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
} // end namespace MultiArrayTools
|
|
|
@ -5,8 +5,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "ranges/rheader.h"
|
#include "ranges/rheader.h"
|
||||||
|
#include "multi_array_header.h"
|
||||||
//#include "multi_array_header.h"
|
|
||||||
|
|
||||||
namespace MAT = MultiArrayTools;
|
namespace MAT = MultiArrayTools;
|
||||||
|
|
||||||
|
@ -14,6 +13,8 @@ namespace {
|
||||||
|
|
||||||
using namespace MAT;
|
using namespace MAT;
|
||||||
|
|
||||||
|
typedef Expressions1 EC1;
|
||||||
|
|
||||||
template <class Factory, typename T>
|
template <class Factory, typename T>
|
||||||
void swapFactory(std::shared_ptr<RangeFactoryBase>& fptr, std::initializer_list<T> ilist)
|
void swapFactory(std::shared_ptr<RangeFactoryBase>& fptr, std::initializer_list<T> ilist)
|
||||||
{
|
{
|
||||||
|
@ -125,15 +126,15 @@ namespace {
|
||||||
|
|
||||||
TEST_F(AnonymousTest, DCast1)
|
TEST_F(AnonymousTest, DCast1)
|
||||||
{
|
{
|
||||||
DynamicRangeFactory arf1(sr1ptr,m3rptr);
|
DynamicRangeFactory<EC1> arf1(sr1ptr,m3rptr);
|
||||||
auto ar1a = std::dynamic_pointer_cast<DynamicRange>( arf1.create() );
|
auto ar1a = std::dynamic_pointer_cast<DynamicRange<EC1>>( arf1.create() );
|
||||||
|
|
||||||
arf1.append(sr2ptr);
|
arf1.append(sr2ptr);
|
||||||
|
|
||||||
auto ar1b = std::dynamic_pointer_cast<DynamicRange>( arf1.create() );
|
auto ar1b = std::dynamic_pointer_cast<DynamicRange<EC1>>( arf1.create() );
|
||||||
|
|
||||||
DynamicRangeFactory arf2(sr1ptr,m3rptr,sr2ptr);
|
DynamicRangeFactory<EC1> arf2(sr1ptr,m3rptr,sr2ptr);
|
||||||
auto ar2 = std::dynamic_pointer_cast<DynamicRange>( arf2.create() );
|
auto ar2 = std::dynamic_pointer_cast<DynamicRange<EC1>>( arf2.create() );
|
||||||
|
|
||||||
EXPECT_EQ(ar1b.get(), ar2.get());
|
EXPECT_EQ(ar1b.get(), ar2.get());
|
||||||
EXPECT_EQ(ar1a->size(), sr1ptr->size() * m3rptr->size());
|
EXPECT_EQ(ar1a->size(), sr1ptr->size() * m3rptr->size());
|
||||||
|
@ -149,9 +150,9 @@ namespace {
|
||||||
|
|
||||||
TEST_F(AnonymousTest, DCast2)
|
TEST_F(AnonymousTest, DCast2)
|
||||||
{
|
{
|
||||||
DynamicRangeFactory arf2(sr1ptr,m3rptr,sr2ptr);
|
DynamicRangeFactory<EC1> arf2(sr1ptr,m3rptr,sr2ptr);
|
||||||
auto ar = std::dynamic_pointer_cast<DynamicRange>( arf2.create() );
|
auto ar = std::dynamic_pointer_cast<DynamicRange<EC1>>( arf2.create() );
|
||||||
auto mr = ar->template scast<SRange,DynamicRange>(1,2);
|
auto mr = ar->template scast<SRange,DynamicRange<EC1>>(1,2);
|
||||||
|
|
||||||
EXPECT_EQ(mr->template getPtr<0>()->size(), sr1ptr->size());
|
EXPECT_EQ(mr->template getPtr<0>()->size(), sr1ptr->size());
|
||||||
EXPECT_EQ(mr->template getPtr<1>()->size(), m3rptr->size() * sr2ptr->size());
|
EXPECT_EQ(mr->template getPtr<1>()->size(), m3rptr->size() * sr2ptr->size());
|
||||||
|
|
Loading…
Reference in a new issue