completely remove pack_num
This commit is contained in:
parent
acda91d792
commit
7fee5aa45d
9 changed files with 32 additions and 249 deletions
|
@ -6,7 +6,8 @@ namespace MultiArrayTools
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
std::ostream& operator<<(std::ostream& out, const std::tuple<T...>& tp)
|
std::ostream& operator<<(std::ostream& out, const std::tuple<T...>& tp)
|
||||||
{
|
{
|
||||||
PackNum<sizeof...(T)-1>::printTuple(out, tp);
|
MA_SFOR(i,0,sizeof...(T)-1,i+1, out << std::get<i>(tp) << ", ";);
|
||||||
|
out << std::get<sizeof...(T)-1>(tp);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "base_def.h"
|
#include "base_def.h"
|
||||||
#include "slice.h"
|
#include "slice.h"
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include "pack_num.h"
|
|
||||||
#include "map_range.h"
|
#include "map_range.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "xfor/iloop.h"
|
#include "xfor/iloop.h"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
#include "multi_array.h"
|
#include "multi_array.h"
|
||||||
|
#include "statics/static_for.h"
|
||||||
|
|
||||||
namespace MultiArrayTools
|
namespace MultiArrayTools
|
||||||
{
|
{
|
||||||
|
@ -246,11 +247,12 @@ namespace MultiArrayTools
|
||||||
(*this) = in;
|
(*this) = in;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert( PackNum<sizeof...(SRanges)-1>::checkIfSameInstance( MAB::mRange->space(), in.mRange->space() ) );
|
MA_SCFOR2(i,0,sizeof...(SRanges),i+1,
|
||||||
|
std::get<i>(MAB::mRange->space()).get() == std::get<i>(in.mRange->space()).get(),
|
||||||
|
operator&&);
|
||||||
for(size_t i = 0; i != mCont.size(); ++i){
|
for(size_t i = 0; i != mCont.size(); ++i){
|
||||||
mCont[i] += in.mCont[i];
|
mCont[i] += in.mCont[i];
|
||||||
}
|
}
|
||||||
//std::transform(mCont.begin(), mCont.end(), in.mCont.begin(), mCont.begin(), std::plus<T>());
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -262,7 +264,9 @@ namespace MultiArrayTools
|
||||||
(*this) = in;
|
(*this) = in;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert( PackNum<sizeof...(SRanges)-1>::checkIfSameInstance( MAB::mRange->space(), in.mRange->space() ) );
|
MA_SCFOR2(i,0,sizeof...(SRanges),i+1,
|
||||||
|
std::get<i>(MAB::mRange->space()).get() == std::get<i>(in.mRange->space()).get(),
|
||||||
|
operator&&);
|
||||||
for(size_t i = 0; i != mCont.size(); ++i){
|
for(size_t i = 0; i != mCont.size(); ++i){
|
||||||
mCont[i] -= in.mCont[i];
|
mCont[i] -= in.mCont[i];
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "mbase_def.h"
|
#include "mbase_def.h"
|
||||||
|
|
||||||
#include "ranges/rheader.h"
|
#include "ranges/rheader.h"
|
||||||
#include "pack_num.h"
|
|
||||||
|
|
||||||
#include "arith.h"
|
#include "arith.h"
|
||||||
#include "xfor/xfor.h"
|
#include "xfor/xfor.h"
|
||||||
|
|
|
@ -1,225 +0,0 @@
|
||||||
// -*- C++ -*-
|
|
||||||
|
|
||||||
#ifndef __pack_num_h__
|
|
||||||
#define __pack_num_h__
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
//#include <type_traits>
|
|
||||||
#include <tuple>
|
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
#include "base_def.h"
|
|
||||||
#include "xfor/exttype.h"
|
|
||||||
|
|
||||||
namespace MultiArrayHelper
|
|
||||||
{
|
|
||||||
template <size_t N>
|
|
||||||
struct PackNum
|
|
||||||
{
|
|
||||||
template <class MA, class ITuple, class... IPtrs>
|
|
||||||
static auto mkElemOperation(const MA& ma, const ITuple& ituple, IPtrs... iptrs)
|
|
||||||
-> decltype(PackNum<N-1>::mkElemOperation(ma, ituple, std::get<N>(ituple), iptrs...))
|
|
||||||
{
|
|
||||||
return PackNum<N-1>::mkElemOperation(ma, ituple, std::get<N>(ituple), iptrs...);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename... T>
|
|
||||||
static void printTuple(std::ostream& out, const std::tuple<T...>& tp)
|
|
||||||
{
|
|
||||||
out << std::get<sizeof...(T)-N-1>(tp) << ", ";
|
|
||||||
PackNum<N-1>::printTuple(out, tp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Ops>
|
|
||||||
static auto mkSteps(std::intptr_t ii, const std::tuple<Ops...>& otp)
|
|
||||||
-> decltype(PackNum<N-1>::mkSteps(ii, otp).extend( std::get<N>(otp).rootSteps(ii)) )
|
|
||||||
{
|
|
||||||
return PackNum<N-1>::mkSteps(ii, otp).extend( std::get<N>(otp).rootSteps(ii));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class RootStepTuple, class IndexClass, class OpClass>
|
|
||||||
static void mkExt(std::array<RootStepTuple,IndexClass::totalDim()>& out,
|
|
||||||
const std::array<std::intptr_t,IndexClass::totalDim()>& siar,
|
|
||||||
const OpClass& second)
|
|
||||||
{
|
|
||||||
std::get<N>(out) = second.rootSteps( std::get<N>(siar) );
|
|
||||||
PackNum<N-1>::mkExt(out, siar, second);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t LAST, class ETuple, class OpTuple, class OpFunction, typename... Args>
|
|
||||||
static inline auto mkOpExpr(std::shared_ptr<OpFunction> f, const ETuple& pos, const OpTuple& ops, Args... args)
|
|
||||||
{
|
|
||||||
typedef typename std::remove_reference<decltype(std::get<N>(ops))>::type NextOpType;
|
|
||||||
static_assert(LAST >= NextOpType::SIZE, "inconsistent array positions");
|
|
||||||
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
|
|
||||||
typedef decltype(std::get<N>(ops).get(getX<NEXT>( pos ))) ArgT;
|
|
||||||
return PackNum<N-1>::template mkOpExpr<NEXT,ETuple,OpTuple,OpFunction,ArgT,Args...>
|
|
||||||
( f, pos, ops, std::get<N>(ops).get(getX<NEXT>( pos )), args...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t LAST, typename V, class ETuple, class OpTuple, class OpFunction, typename... Args>
|
|
||||||
static inline auto mkVOpExpr(std::shared_ptr<OpFunction> f, const ETuple& pos, const OpTuple& ops, Args... args)
|
|
||||||
{
|
|
||||||
typedef typename std::remove_reference<decltype(std::get<N>(ops))>::type NextOpType;
|
|
||||||
static_assert(LAST >= NextOpType::SIZE, "inconsistent array positions");
|
|
||||||
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
|
|
||||||
typedef decltype(std::get<N>(ops).template vget<V>(getX<NEXT>( pos ))) ArgT;
|
|
||||||
return PackNum<N-1>::template mkVOpExpr<NEXT,V,ETuple,OpTuple,OpFunction,ArgT,Args...>
|
|
||||||
( f, pos, ops, std::get<N>(ops).template vget<V>(getX<NEXT>( pos )), args...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OpTuple, class Expr>
|
|
||||||
static auto mkLoop( const OpTuple& ot, Expr exp )
|
|
||||||
-> decltype(std::get<N>(ot).loop( PackNum<N-1>::mkLoop(ot,exp) ))
|
|
||||||
{
|
|
||||||
return std::get<N>(ot).loop( PackNum<N-1>::mkLoop(ot,exp) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Op, class... SRanges>
|
|
||||||
static void mkSliceBlocks(std::array<size_t, sizeof...(SRanges)+1>& blocks,
|
|
||||||
const ContainerIndex<T,typename SRanges::IndexType...>& index,
|
|
||||||
const Op& op, size_t total = 1)
|
|
||||||
{
|
|
||||||
const size_t tmp =
|
|
||||||
op.rootSteps(reinterpret_cast<std::intptr_t>
|
|
||||||
( index.template getPtr<N>().get() ) )
|
|
||||||
.val();
|
|
||||||
std::get<N+1>(blocks) = tmp;
|
|
||||||
PackNum<N-1>::template mkSliceBlocks<T,Op,SRanges...>(blocks, index, op, total * tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... SRanges>
|
|
||||||
static bool checkIfSameInstance(const std::tuple<std::shared_ptr<SRanges>...>& rtp1,
|
|
||||||
const std::tuple<std::shared_ptr<SRanges>...>& rtp2)
|
|
||||||
{
|
|
||||||
return std::get<N>(rtp1).get() == std::get<N>(rtp2).get() and PackNum<N-1>::checkIfSameInstance(rtp1,rtp2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MA, class ITuple, class... Indices>
|
|
||||||
static inline auto mkMapOp(const MA& ma, const ITuple& itp, const std::shared_ptr<Indices>&... inds)
|
|
||||||
-> decltype(PackNum<N-1>::mkMapOp(ma, itp, std::get<N>(itp), inds...))
|
|
||||||
{
|
|
||||||
return PackNum<N-1>::mkMapOp(ma, itp, std::get<N>(itp), inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t LAST,class OpTuple, class ETuple>
|
|
||||||
static inline void setOpPos(OpTuple& ot, const ETuple& et)
|
|
||||||
{
|
|
||||||
typedef typename std::remove_reference<decltype(std::get<N>(ot))>::type NextOpType;
|
|
||||||
static_assert(LAST >= NextOpType::SIZE, "inconsistent array positions");
|
|
||||||
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
|
|
||||||
std::get<N>( ot ).set( getX<NEXT>( et ) );
|
|
||||||
PackNum<N-1>::template setOpPos<NEXT,OpTuple,ETuple>(ot, et);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct PackNum<0>
|
|
||||||
{
|
|
||||||
template <class MA, class ITuple, class... IPtrs>
|
|
||||||
static auto mkElemOperation(const MA& ma, const ITuple& ituple, IPtrs... iptrs)
|
|
||||||
-> decltype(ma(iptrs...))
|
|
||||||
{
|
|
||||||
return ma(iptrs...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... T>
|
|
||||||
static void printTuple(std::ostream& out, const std::tuple<T...>& tp)
|
|
||||||
{
|
|
||||||
out << std::get<sizeof...(T)-1>(tp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Ops>
|
|
||||||
static auto mkSteps(std::intptr_t ii, const std::tuple<Ops...>& otp)
|
|
||||||
-> decltype(std::get<0>(otp).rootSteps(ii))
|
|
||||||
{
|
|
||||||
return std::get<0>(otp).rootSteps(ii);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class RootStepTuple, class IndexClass, class OpClass>
|
|
||||||
static void mkExt(std::array<RootStepTuple,IndexClass::totalDim()>& out,
|
|
||||||
const std::array<std::intptr_t,IndexClass::totalDim()>& siar,
|
|
||||||
const OpClass& second)
|
|
||||||
{
|
|
||||||
std::get<0>(out) = second.rootSteps( std::get<0>(siar) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t LAST, class ETuple, class OpTuple, class OpFunction, typename... Args>
|
|
||||||
static inline auto mkOpExpr(std::shared_ptr<OpFunction> f, const ETuple& pos, const OpTuple& ops, const Args&... args)
|
|
||||||
{
|
|
||||||
typedef typename std::remove_reference<decltype(std::get<0>(ops))>::type NextOpType;
|
|
||||||
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
|
|
||||||
static_assert(NEXT == 0, "inconsistent array positions");
|
|
||||||
if constexpr(OpFunction::FISSTATIC){
|
|
||||||
return OpFunction::apply(std::get<0>(ops).get(getX<0>( pos )), args...);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return (*f)(std::get<0>(ops).get(getX<0>( pos )), args...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t LAST, typename V, class ETuple, class OpTuple, class OpFunction, typename... Args>
|
|
||||||
static inline auto mkVOpExpr(std::shared_ptr<OpFunction> f, const ETuple& pos, const OpTuple& ops, const Args&... args)
|
|
||||||
{
|
|
||||||
typedef typename std::remove_reference<decltype(std::get<0>(ops))>::type NextOpType;
|
|
||||||
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
|
|
||||||
static_assert(NEXT == 0, "inconsistent array positions");
|
|
||||||
if constexpr(OpFunction::FISSTATIC){
|
|
||||||
return OpFunction::apply(std::get<0>(ops).template vget<V>(getX<0>( pos )), args...);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return (*f)(std::get<0>(ops).template vget<V>(getX<0>( pos )), args...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OpTuple, class Expr>
|
|
||||||
static auto mkLoop( const OpTuple& ot, Expr exp )
|
|
||||||
-> decltype(std::get<0>(ot).loop( exp ))
|
|
||||||
{
|
|
||||||
return std::get<0>(ot).loop( exp );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Op, class... SRanges>
|
|
||||||
static void mkSliceBlocks(std::array<size_t, sizeof...(SRanges)+1>& blocks,
|
|
||||||
const ContainerIndex<T,typename SRanges::IndexType...>& index,
|
|
||||||
const Op& op, size_t total = 1)
|
|
||||||
{
|
|
||||||
const size_t tmp =
|
|
||||||
op.rootSteps(reinterpret_cast<std::intptr_t>
|
|
||||||
( index.template getPtr<0>().get() ) )
|
|
||||||
.val();
|
|
||||||
std::get<1>(blocks) = tmp;
|
|
||||||
std::get<0>(blocks) = total * tmp; // this is not correct, but not used so far ... !!!
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... SRanges>
|
|
||||||
static bool checkIfSameInstance(const std::tuple<std::shared_ptr<SRanges>...>& rtp1,
|
|
||||||
const std::tuple<std::shared_ptr<SRanges>...>& rtp2)
|
|
||||||
{
|
|
||||||
return std::get<0>(rtp1).get() == std::get<0>(rtp2).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MA, class ITuple, class... Indices>
|
|
||||||
static inline auto mkMapOp(const MA& ma, const ITuple& itp, const std::shared_ptr<Indices>&... inds)
|
|
||||||
-> decltype(ma.exec(std::get<0>(itp), inds...))
|
|
||||||
{
|
|
||||||
return ma.exec(std::get<0>(itp), inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t LAST,class OpTuple, class ETuple>
|
|
||||||
static inline void setOpPos(OpTuple& ot, const ETuple& et)
|
|
||||||
{
|
|
||||||
typedef typename std::remove_reference<decltype(std::get<0>(ot))>::type NextOpType;
|
|
||||||
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
|
|
||||||
static_assert(NEXT == 0, "inconsistent array positions");
|
|
||||||
std::get<0>( ot ).set( getX<NEXT>( et ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // end namespace MultiArrayHelper
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -243,8 +243,9 @@ namespace MultiArrayTools
|
||||||
SliceDef<T,SRanges...>& SliceDef<T,SRanges...>::operator=(const OperationRoot<T,ORanges...>& op)
|
SliceDef<T,SRanges...>& SliceDef<T,SRanges...>::operator=(const OperationRoot<T,ORanges...>& op)
|
||||||
{
|
{
|
||||||
std::array<size_t,sizeof...(SRanges)+1> blocks;
|
std::array<size_t,sizeof...(SRanges)+1> blocks;
|
||||||
PackNum<sizeof...(SRanges)-1>::
|
MA_SFOR(i,0,sizeof...(SRanges),i+1,
|
||||||
template mkSliceBlocks<T,OperationRoot<T,ORanges...>,SRanges...>(blocks, mIndex, op);
|
std::get<i+1>(blocks) = op.rootSteps(reinterpret_cast<std::intptr_t>
|
||||||
|
( mIndex.template getPtr<i>().get())).val(););
|
||||||
mSl.format(blocks);
|
mSl.format(blocks);
|
||||||
mSl.mData = op.data();
|
mSl.mData = op.data();
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -264,8 +265,9 @@ namespace MultiArrayTools
|
||||||
ConstSliceDef<T,SRanges...>& ConstSliceDef<T,SRanges...>::operator=(const ConstOperationRoot<T,ORanges...>& op)
|
ConstSliceDef<T,SRanges...>& ConstSliceDef<T,SRanges...>::operator=(const ConstOperationRoot<T,ORanges...>& op)
|
||||||
{
|
{
|
||||||
std::array<size_t,sizeof...(SRanges)+1> blocks;
|
std::array<size_t,sizeof...(SRanges)+1> blocks;
|
||||||
PackNum<sizeof...(SRanges)-1>::
|
MA_SFOR(i,0,sizeof...(SRanges),i+1,
|
||||||
template mkSliceBlocks<T,ConstOperationRoot<T,ORanges...>,SRanges...>(blocks, mIndex, op);
|
std::get<i+1>(blocks) = op.rootSteps(reinterpret_cast<std::intptr_t>
|
||||||
|
( mIndex.template getPtr<i>().get())).val(););
|
||||||
mSl.format(blocks);
|
mSl.format(blocks);
|
||||||
mSl.mData = op.data();
|
mSl.mData = op.data();
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -276,8 +278,9 @@ namespace MultiArrayTools
|
||||||
ConstSliceDef<T,SRanges...>& ConstSliceDef<T,SRanges...>::operator=(const OperationRoot<T,ORanges...>& op)
|
ConstSliceDef<T,SRanges...>& ConstSliceDef<T,SRanges...>::operator=(const OperationRoot<T,ORanges...>& op)
|
||||||
{
|
{
|
||||||
std::array<size_t,sizeof...(SRanges)+1> blocks;
|
std::array<size_t,sizeof...(SRanges)+1> blocks;
|
||||||
PackNum<sizeof...(SRanges)-1>::
|
MA_SFOR(i,0,sizeof...(SRanges),i+1,
|
||||||
template mkSliceBlocks<T,OperationRoot<T,ORanges...>,SRanges...>(blocks, mIndex, op);
|
std::get<i+1>(blocks) = op.rootSteps(reinterpret_cast<std::intptr_t>
|
||||||
|
( mIndex.template getPtr<i>().get())).val(););
|
||||||
mSl.format(blocks);
|
mSl.format(blocks);
|
||||||
mSl.mData = op.data();
|
mSl.mData = op.data();
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
@ -108,13 +108,13 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
template <class Op>
|
template <class Op>
|
||||||
static Slice<T,SRanges...> mkSlice( const typename Slice<T,SRanges...>::IndexType& ind,
|
static Slice<T,SRanges...> mkSlice( const typename Slice<T,SRanges...>::IndexType& ind,
|
||||||
const Op& op )
|
const Op& op )
|
||||||
{
|
{
|
||||||
Slice<T,SRanges...> out(ind->range()->space(), &*ind);
|
Slice<T,SRanges...> out(ind->range()->space(), &*ind);
|
||||||
std::array<size_t,sizeof...(SRanges)+1> ff;
|
std::array<size_t,sizeof...(SRanges)+1> ff;
|
||||||
for(size_t i = 0; i != sizeof...(SRanges)+1; ++i){
|
MA_SFOR(i,0,sizeof...(SRanges),i+1,
|
||||||
PackNum<sizeof...(SRanges)-1>::mkSliceBlocks(ff, ind, op);
|
std::get<i+1>(ff) = op.rootSteps(reinterpret_cast<std::intptr_t>
|
||||||
}
|
( ind.template getPtr<i>().get())).val(););
|
||||||
out.format(ff);
|
out.format(ff);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -145,9 +145,9 @@ namespace MultiArrayTools
|
||||||
{
|
{
|
||||||
ConstSlice<T,SRanges...> out(ind->range()->space(), &*ind);
|
ConstSlice<T,SRanges...> out(ind->range()->space(), &*ind);
|
||||||
std::array<size_t,sizeof...(SRanges)+1> ff;
|
std::array<size_t,sizeof...(SRanges)+1> ff;
|
||||||
for(size_t i = 0; i != sizeof...(SRanges)+1; ++i){
|
MA_SFOR(i,0,sizeof...(SRanges),i+1,
|
||||||
PackNum<sizeof...(SRanges)-1>::mkSliceBlocks(ff, ind, op);
|
std::get<i+1>(ff) = op.rootSteps(reinterpret_cast<std::intptr_t>
|
||||||
}
|
( ind.template getPtr<i>().get())).val(););
|
||||||
out.format(ff);
|
out.format(ff);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace MultiArrayTools
|
||||||
//static_assert(abs(idx.value - END) >= abs(incr(idx) - END),
|
//static_assert(abs(idx.value - END) >= abs(incr(idx) - END),
|
||||||
// "this turns out to be a static endless loop");
|
// "this turns out to be a static endless loop");
|
||||||
auto tmp = f(idxm);
|
auto tmp = f(idxm);
|
||||||
if constexpr(incr(idx) == END){
|
if constexpr(incr(idx) >= END){
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -30,7 +30,7 @@ namespace MultiArrayTools
|
||||||
//static_assert(abs(idx.value - END) >= abs(incr(idx) - END),
|
//static_assert(abs(idx.value - END) >= abs(incr(idx) - END),
|
||||||
// "this turns out to be a static endless loop");
|
// "this turns out to be a static endless loop");
|
||||||
auto tmp = f(idxm);
|
auto tmp = f(idxm);
|
||||||
if constexpr(incr(idx) == END){
|
if constexpr(incr(idx) >= END){
|
||||||
return conc(tmp, arg);
|
return conc(tmp, arg);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -45,7 +45,7 @@ namespace MultiArrayTools
|
||||||
constexpr auto idxm = std::integral_constant<size_t, BEG+OFF>{};
|
constexpr auto idxm = std::integral_constant<size_t, BEG+OFF>{};
|
||||||
//static_assert(abs(idx.value - END) >= abs(incr(idx) - END),
|
//static_assert(abs(idx.value - END) >= abs(incr(idx) - END),
|
||||||
// "this turns out to be a static endless loop");
|
// "this turns out to be a static endless loop");
|
||||||
if constexpr(BEG == END){
|
if constexpr(BEG >= END){
|
||||||
return create(args...);
|
return create(args...);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -58,6 +58,7 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
#define MA_SFOR(i,beg,end,incr,expr) sfor<beg,end,0>([&](auto i) constexpr { return incr; }, [&](auto i){ expr return 0; }, [&](auto f, auto next) { return 0; })
|
#define MA_SFOR(i,beg,end,incr,expr) sfor<beg,end,0>([&](auto i) constexpr { return incr; }, [&](auto i){ expr return 0; }, [&](auto f, auto next) { return 0; })
|
||||||
#define MA_SCFOR(i,beg,end,incr,expr,conc) sfor<beg,end,0>([&](auto i) constexpr { return incr; }, [&](auto i){ return expr; }, [&](auto f, auto next) { return f.conc(next); })
|
#define MA_SCFOR(i,beg,end,incr,expr,conc) sfor<beg,end,0>([&](auto i) constexpr { return incr; }, [&](auto i){ return expr; }, [&](auto f, auto next) { return f.conc(next); })
|
||||||
|
#define MA_SCFOR2(i,beg,end,incr,expr,conc) sfor<beg,end,0>([&](auto i) constexpr { return incr; }, [&](auto i){ return expr; }, [&](auto a, auto b) { return conc(a,b); })
|
||||||
#define MA_SRFOR(i,beg,end,decr,expr) sfor<beg,end,-1>([&](auto i) constexpr { return decr; }, [&](auto i){ expr return 0; }, [&](auto f, auto next) { return 0; })
|
#define MA_SRFOR(i,beg,end,decr,expr) sfor<beg,end,-1>([&](auto i) constexpr { return decr; }, [&](auto i){ expr return 0; }, [&](auto f, auto next) { return 0; })
|
||||||
#define MA_SCRFOR(i,beg,end,decr,expr,conc) sfor<beg,end,-1>([&](auto i) constexpr { return decr; }, [&](auto i){ return expr; }, [&](auto f, auto next) { return f.conc(next); })
|
#define MA_SCRFOR(i,beg,end,decr,expr,conc) sfor<beg,end,-1>([&](auto i) constexpr { return decr; }, [&](auto i){ return expr; }, [&](auto f, auto next) { return f.conc(next); })
|
||||||
#define MA_SCRAFOR(i,beg,end,decr,expr,conc,arg) sfor<beg,end,-1>([&](auto i) constexpr { return decr; }, [&](auto i){ return expr; }, [&](auto f, auto next) { return f.conc(next); }, arg)
|
#define MA_SCRAFOR(i,beg,end,decr,expr,conc,arg) sfor<beg,end,-1>([&](auto i) constexpr { return decr; }, [&](auto i){ return expr; }, [&](auto f, auto next) { return f.conc(next); }, arg)
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
#include "base_def.h"
|
#include "base_def.h"
|
||||||
#include "mbase_def.h"
|
#include "mbase_def.h"
|
||||||
|
|
||||||
#include "pack_num.h"
|
#include "statics/static_for.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace MultiArrayTools
|
namespace MultiArrayTools
|
||||||
|
@ -32,7 +33,7 @@ namespace MultiArrayTools
|
||||||
inline auto apply(const MultiArray<T,Ranges...>& ma)
|
inline auto apply(const MultiArray<T,Ranges...>& ma)
|
||||||
-> OperationRoot<T,Ranges...>
|
-> OperationRoot<T,Ranges...>
|
||||||
{
|
{
|
||||||
return PackNum<sizeof...(Ranges)-1>::mkElemOperation(ma, ituple);
|
return MA_CFOR(i,0,sizeof...(Ranges),i+1,return std::get<i>(ituple);,ma);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in a new issue