This commit is contained in:
Christian Zimmermann 2017-08-11 11:30:27 +02:00
parent 1ffffa568f
commit a9611b40e5
6 changed files with 145 additions and 9 deletions

View file

@ -13,16 +13,31 @@ namespace MultiArrayTools
// purely virtual at the moment
/***************************
* OperationTemplate *
***************************/
template <class OperationClass>
template <class Second>
Operation<OperationClass,Second> OperationTemplate<OperationClass>::operator+(Second&& in) const
{
return Operation<double,std::plus<double>,OperationClass,Second>(*this, in);
}
/*************************
* OperationMaster *
*************************/
template <typename T, class... Ranges>
OperationMaster<T,Ranges...>::OperationMaster(MutableMultiArrayBase& ma,
const ContainerRange<Ranges...>::IndexType& index) :
OperationMaster<T,Ranges...>::
OperationMaster(MutableMultiArrayBase& ma,
std::shared_ptr<ContainerRange<Ranges...>::IndexType>& index) :
mArrayRef(ma), mIndex()
{
(*mIndex) = index; // implement corresp member fucntion in MultiIndex
(*mIndex) = *index;
for(*mIndex = 0; mIndex->pos() != mIndex->max(); ++(*mIndex)){
get() = mSecond.get();
}
}
template <typename T, class... Ranges>
@ -69,6 +84,12 @@ namespace MultiArrayTools
mIndex(indices...);
}
template <typename T, class... Ranges>
OperationMaster<T,Ranges...> OperationRoot<T,Ranges...>::operator=(const OperationBase<T>& in)
{
return OperationMaster<T,Ranges...>(mArrayRef, in, mIndex);
}
template <typename T, class... Ranges>
const T& OperationRoot<T,Ranges...>::get() const
{

View file

@ -52,6 +52,15 @@ namespace MultiArrayTools
virtual T& get() = 0;
};
template <class OperationClass>
class OperationTemplate
{
public:
template <class Second>
Operation<OperationClass,Second> operator+(const Second& in) const;
};
template <typename T, class... Ranges>
class OperationMaster : public MutableOperationBase<T>
{
@ -60,17 +69,18 @@ namespace MultiArrayTools
typedef OperationBase<T> OB;
typedef typename MultiRange<Ranges...>::IndexType IndexType;
OperationMaster(OperationRoot<T,Ranges...>&& root);
OperationMaster(MutableMultiArrayBase& ma, OperationBase<T>& second,
const ContainerRange<Ranges...>::IndexType& index);
virtual T& get() override;
virtual const T& get() const override;
protected:
void performAssignment(const MultiArrayOperationBase<T>& in);
//void performAssignment(const OperationBase<T>& in);
OperationBase<T> const& mSecond;
MutableMultiArrayBase<T,CRange>& mArrayRef;
mutable IndexType mIndex;
std::shared_ptr<IndexType> mIndex;
};
@ -110,6 +120,8 @@ namespace MultiArrayTools
OperationRoot(MutableMultiArrayBase<T,CRange>& ma,
const std::shared_ptr<typename Ranges::IndexType>&... indices);
OperationMaster<T,Ranges...> operator=(const OperationBase<T>& in);
virtual const T& get() const override;
virtual T& get() override;

View file

@ -31,6 +31,15 @@ namespace MultiArrayTools
return *this;
}
template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator=(ContainerIndex<Indices...>& ci)
{
IndexI::operator=(in);
PackNum<sizeof...(Indices)-1>::copyInst(mIPack, ci);
IB::mPos = PackNum<sizeof...(Indices)-1>::makePos(mIPack);
return *this;
}
template <class... Indices>
template <class MRange>
MultiIndex<Indices...>::MultiIndex(const std::shared_ptr<MRange>& range) :

View file

@ -33,6 +33,7 @@ namespace MultiArrayTools
// ( have to assign sub-indices (ptr!) correctly )
MultiIndex(const MultiIndex& in);
MultiIndex& operator=(const MultiIndex& in);
MultiIndex& operator=(const ContainerIndex<Indices...>& ci);
template <class MRange>
MultiIndex(const std::shared_ptr<MRange>& range);

78
src/op_unit_test.cc Normal file
View file

@ -0,0 +1,78 @@
// -*- C++ -*-
#include <cstdlib>
#include "gtest/gtest.h"
#include <iostream>
#include "multi_array_header.h"
namespace MAT = MultiArrayTools;
namespace {
using namespace MAT;
template <class Factory, typename T>
void swapFactory(std::shared_ptr<RangeFactoryBase>& fptr, std::initializer_list<T> ilist)
{
std::vector<T> tmp = ilist;
auto nptr = std::make_shared<Factory>( tmp );
fptr = nptr;
}
template <class Factory, class... Rs>
void swapMFactory(std::shared_ptr<RangeFactoryBase>& fptr, const Rs&... rs)
{
auto nptr = std::make_shared<Factory>( rs... );
fptr = nptr;
}
template <typename... Ts>
auto mkt(Ts&&... ts) -> decltype(std::make_tuple(ts...))
{
return std::make_tuple(ts...);
}
class OpTest_1Dim : public ::testing::Test
{
protected:
typedef SingleRangeFactory<char,RangeType::ANY> SRF;
typedef SRF::oType SRange;
typedef ContainerRangeFactory<SRange> CRF;
typedef CRF::oType CRange;
OpTest_1Dim()
{
swapFactory<SRF>(rfbptr, {'a', 'l', 'f', 'g'} );
srptr = std::dynamic_pointer_cast<SRange>( rfbptr->create() );
swapMFactory<CRF>(srptr);
crptr = std::dynamic_pointer_cast<CRange>( rfbptr->create() );
}
std::shared_ptr<RangeFactoryBase> rfbptr;
std::shared_ptr<SRange> srptr;
std::shared_ptr<CRange> crptr;
std::vector<double> v1 = { 2.917, 9.436, 0.373, 7.192 };
std::vector<double> v2 = { 8.870, 4.790, 8.215, 5.063 };
};
TEST_F(OpTest_1Dim, ExecOp)
{
MultiArray<double,CRange> ma1(crptr, v1);
MultiArray<double,CRange> ma2(crptr, v2);
MultiArray<double,CRange> res(crptr);
std::map<std::string,std::shared_ptr<SRange::IndexType> > m;
res(m["mu"]) = ma1(m["mu"]) + ma2(m["mu"]);
}
} // anonymous namspace
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View file

@ -119,6 +119,14 @@ namespace MultiArrayHelper
PackNum<N-1>::copy(ip, ind);
}
template <template<class...> class IndexType, class... Indices>
static void copyInst(std::tuple<std::shared_ptr<Indices>...>& ip,
const IndexType<Indices...>& ind)
{
std::get<N>(ip) = ind.template getPtr<N>() ;
PackNum<N-1>::copy(ip, ind);
}
template <class... Indices>
static size_t makePos(const std::tuple<std::shared_ptr<Indices>...>& iPtrTup)
{
@ -220,6 +228,13 @@ namespace MultiArrayHelper
std::get<0>(ip) = std::shared_ptr<SubIndexType>( new SubIndexType( ind.template get<0>() ) );
}
template <template<class...> class IndexType, class... Indices>
static void copyInst(std::tuple<std::shared_ptr<Indices>...>& ip,
const IndexType<Indices...>& ind)
{
std::get<0>(ip) = ind.template getPtr<0>();
}
template <class... Indices>
static size_t makePos(const std::tuple<std::shared_ptr<Indices>...>& iPtrTup)
{