reorganize source files
This commit is contained in:
parent
45bc1686c9
commit
c04863f93f
10 changed files with 684 additions and 619 deletions
129
src/index_base.cc
Normal file
129
src/index_base.cc
Normal file
|
@ -0,0 +1,129 @@
|
|||
|
||||
#include "index_base.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
/************************
|
||||
* IndefinitIndexBase *
|
||||
************************/
|
||||
|
||||
bool IndefinitIndexBase::link(IndefinitIndexBase* toLink)
|
||||
{
|
||||
if(toLink->rangeType() != rangeType() and toLink->name() == name()){
|
||||
// throw !!
|
||||
}
|
||||
|
||||
if(toLink->rangeType() == rangeType() and toLink->name() == name()){
|
||||
if(mLinked == toLink){
|
||||
return true; // dont link twice the same
|
||||
}
|
||||
else if(mLinked == nullptr){
|
||||
mLinked = toLink;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return mLinked->link(toLink);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void IndefinitIndexBase::freeLinked()
|
||||
{
|
||||
if(linked()){
|
||||
mLinked->freeLinked();
|
||||
mLinked = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool IndefinitIndexBase::linked() const
|
||||
{
|
||||
return mLinked != nullptr;
|
||||
}
|
||||
|
||||
void IndefinitIndexBase::setPos(size_t pos)
|
||||
{
|
||||
mPos = pos;
|
||||
if(linked()){
|
||||
mLinked->setPos(pos);
|
||||
}
|
||||
}
|
||||
|
||||
size_t IndefinitIndexBase::max() const
|
||||
{
|
||||
return static_cast<size_t>( -1 );
|
||||
}
|
||||
|
||||
size_t IndefinitIndexBase::outOfRange() const
|
||||
{
|
||||
int res = pos() - max();
|
||||
return res > 0 ? static_cast<size_t>(res) : 0;
|
||||
}
|
||||
|
||||
/**************
|
||||
* IndexBase *
|
||||
**************/
|
||||
|
||||
template <class Index>
|
||||
Index& IndexBase<Index>::operator=(const Index& in)
|
||||
{
|
||||
setPos( evaluate(in) );
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
Index& IndexBase<Index>::operator=(size_t pos)
|
||||
{
|
||||
setPos( pos );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
Index& IndexBase<Index>::operator++()
|
||||
{
|
||||
setPos( ++mPos );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
Index& IndexBase<Index>::operator--()
|
||||
{
|
||||
setPos( --mPos );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
Index& IndexBase<Index>::operator+=(int n)
|
||||
{
|
||||
setPos( mPos += n );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
Index& IndexBase<Index>::operator-=(int n)
|
||||
{
|
||||
setPos( mPos -= n );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
bool IndexBase<Index>::operator==(const Index& i)
|
||||
{
|
||||
return mRange == i.mRange and mPos == i.mPos;
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
bool IndexBase<Index>::operator!=(const Index& i)
|
||||
{
|
||||
return mRange != i.mRange or mPos != i.mPos;
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
size_t IndexBase<Index>::max() const
|
||||
{
|
||||
return mRange->size();
|
||||
}
|
||||
|
||||
|
||||
}
|
588
src/me.cc
588
src/me.cc
|
@ -1,588 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
#include "me.h"
|
||||
|
||||
namespace ME
|
||||
{
|
||||
|
||||
/*********************
|
||||
* MultiRangeType *
|
||||
*********************/
|
||||
|
||||
MultiRangeType& MultiRangeType::operator=(RangeType& type)
|
||||
{
|
||||
setType(type);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultiRangeType& MultiRangeType::operator=(const std::vector<MultiRangeType>& multiType)
|
||||
{
|
||||
setMultiType(multiType);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultiRangeType& MultiRangeType::operator[](size_t num)
|
||||
{
|
||||
return mMultiType->at(num);
|
||||
}
|
||||
|
||||
const MultiRangeType& MultiRangeType::operator[](size_t num) const
|
||||
{
|
||||
return mMultiType->at(num);
|
||||
}
|
||||
|
||||
bool MultiRangeType::multi() const
|
||||
{
|
||||
return mType != nullptr;
|
||||
}
|
||||
|
||||
bool MultiRangeType::operator==(const MultiRangeType& in) const
|
||||
{
|
||||
if(multi()){
|
||||
return *mMultiType == *in.mMultiType;
|
||||
}
|
||||
else {
|
||||
return mType == in.mType;
|
||||
}
|
||||
}
|
||||
|
||||
bool MultiRangeType::operator!=(const MultiRangeType& in) const
|
||||
{
|
||||
if(multi()){
|
||||
return *mMultiType != *in.mMultiType;
|
||||
}
|
||||
else {
|
||||
return mType != in.mType;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiRangeType::setType(RangeType type)
|
||||
{
|
||||
mType = type;
|
||||
if(mMultiType != nullptr){
|
||||
delete mMultiType;
|
||||
}
|
||||
mMultiType = nullptr;
|
||||
}
|
||||
|
||||
void MultiRangeType::setMultiType(const std::vector<MultiRangeType>& multiType)
|
||||
{
|
||||
mMultiType = new std::vector<MultiRangeType>( multiType );
|
||||
mType = RangeType::NIL;
|
||||
}
|
||||
|
||||
/******************
|
||||
* RangeBase *
|
||||
******************/
|
||||
|
||||
template <class Index>
|
||||
bool RangeBase<Index>::isSubRange() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*********************
|
||||
* SubRangeBase *
|
||||
*********************/
|
||||
|
||||
template <class Index>
|
||||
bool SubRangeBase<Index>::isSubRange() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/********************
|
||||
* SingleRange *
|
||||
********************/
|
||||
|
||||
template <typename U, RangeType TYPE>
|
||||
const U& SingleRange<U,TYPE>::get(size_t pos) const
|
||||
{
|
||||
return mSpace[pos];
|
||||
}
|
||||
|
||||
template <typename U, RangeType TYPE>
|
||||
size_t SingleRange<U,TYPE>::get(const U& metaPos) const
|
||||
{
|
||||
size_t cnt = 0;
|
||||
for(auto& x: mSpace){
|
||||
if(x == metaPos){
|
||||
return cnt;
|
||||
}
|
||||
++cnt;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/************************
|
||||
* IndefinitIndexBase *
|
||||
************************/
|
||||
|
||||
bool IndefinitIndexBase::link(IndefinitIndexBase* toLink)
|
||||
{
|
||||
if(toLink->rangeType() != rangeType() and toLink->name() == name()){
|
||||
// throw !!
|
||||
}
|
||||
|
||||
if(toLink->rangeType() == rangeType() and toLink->name() == name()){
|
||||
if(mLinked == toLink){
|
||||
return true; // dont link twice the same
|
||||
}
|
||||
else if(mLinked == nullptr){
|
||||
mLinked = toLink;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return mLinked->link(toLink);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void IndefinitIndexBase::freeLinked()
|
||||
{
|
||||
if(linked()){
|
||||
mLinked->freeLinked();
|
||||
mLinked = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool IndefinitIndexBase::linked() const
|
||||
{
|
||||
return mLinked != nullptr;
|
||||
}
|
||||
|
||||
void IndefinitIndexBase::setPos(size_t pos)
|
||||
{
|
||||
mPos = pos;
|
||||
if(linked()){
|
||||
mLinked->setPos(pos);
|
||||
}
|
||||
}
|
||||
|
||||
size_t IndefinitIndexBase::max() const
|
||||
{
|
||||
return static_cast<size_t>( -1 );
|
||||
}
|
||||
|
||||
size_t IndefinitIndexBase::outOfRange() const
|
||||
{
|
||||
int res = pos() - max();
|
||||
return res > 0 ? static_cast<size_t>(res) : 0;
|
||||
}
|
||||
|
||||
/**************
|
||||
* IndexBase *
|
||||
**************/
|
||||
|
||||
template <class Index>
|
||||
Index& IndexBase<Index>::operator=(const Index& in)
|
||||
{
|
||||
setPos( evaluate(in) );
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
Index& IndexBase<Index>::operator=(size_t pos)
|
||||
{
|
||||
setPos( pos );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
Index& IndexBase<Index>::operator++()
|
||||
{
|
||||
setPos( ++mPos );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
Index& IndexBase<Index>::operator--()
|
||||
{
|
||||
setPos( --mPos );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
Index& IndexBase<Index>::operator+=(int n)
|
||||
{
|
||||
setPos( mPos += n );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
Index& IndexBase<Index>::operator-=(int n)
|
||||
{
|
||||
setPos( mPos -= n );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
bool IndexBase<Index>::operator==(const Index& i)
|
||||
{
|
||||
return mRange == i.mRange and mPos == i.mPos;
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
bool IndexBase<Index>::operator!=(const Index& i)
|
||||
{
|
||||
return mRange != i.mRange or mPos != i.mPos;
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
size_t IndexBase<Index>::max() const
|
||||
{
|
||||
return mRange->size();
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
* SingleIndexBase *
|
||||
********************/
|
||||
|
||||
template <typename U, IndexType TYPE>
|
||||
const U& SingleIndexBase<U,TYPE>::getMetaPos() const
|
||||
{
|
||||
return dynamic_cast<SingleRange*>( mRange )->get(mPos);
|
||||
}
|
||||
|
||||
template <typename U, IndexType TYPE>
|
||||
size_t dim() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <typename U, IndexType TYPE>
|
||||
size_t SingleIndexBase<TYPE>::evaluate(const Index& in)
|
||||
{
|
||||
return in.mPos;
|
||||
}
|
||||
|
||||
template <typename U, IndexType TYPE>
|
||||
void linkTo(IndefinitIndexBase* target)
|
||||
{
|
||||
target->link(this);
|
||||
}
|
||||
|
||||
/*******************
|
||||
* MultiIndexBase *
|
||||
*******************/
|
||||
|
||||
namespace
|
||||
{
|
||||
template <class MultiIndex, size_t N>
|
||||
IndefinitIndexBase& getIndex(MultiIndex& in, size_t n)
|
||||
{
|
||||
if(n == N){
|
||||
return in.getIndex<N>();
|
||||
}
|
||||
else {
|
||||
return getIndex<N-1>(in, n);
|
||||
}
|
||||
}
|
||||
|
||||
template <class MultiIndex>
|
||||
IndefinitIndexBase& getIndex<MultiIndex,0>(MultiIndex& in, size_t n)
|
||||
{
|
||||
return in.getIndex<0>();
|
||||
}
|
||||
|
||||
template <size_t N, class MultiIndex>
|
||||
size_t evaluate_x(const MultiIndex& index)
|
||||
{
|
||||
const auto& subIndex = index.getIndex<N>();
|
||||
return evaluate_x<N-1>(index) * subIndex.size() + subIndex.pos();
|
||||
}
|
||||
|
||||
template <class MultiIndex>
|
||||
size_t evaluate_x<0>(const MultiIndex& index)
|
||||
{
|
||||
const auto& subIndex = index.getIndex<0>();
|
||||
return subIndex.pos();
|
||||
}
|
||||
|
||||
template <class MultiIndex>
|
||||
void plus(MultiIndex& index, size_t digit, int num)
|
||||
{
|
||||
IndefinitIndexBase& si = index.getIndex(digit);
|
||||
si.setPos( si.pos() + num );
|
||||
size_t oor = si.outOfRange();
|
||||
if(oor and digit != MultiIndex::mult - 1){
|
||||
plus(index, digit + 1, 1);
|
||||
plus(index, digit, oor - max());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class... Indices>
|
||||
MultiIndex& MultiIndex<Indices...>::operator++()
|
||||
{
|
||||
setPos( pos() + 1 );
|
||||
plus(*this, 0, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
MultiIndex& MultiIndex<Indices...>::operator--()
|
||||
{
|
||||
setPos( pos() - 1 );
|
||||
plus(*this, 0, -1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
MultiIndex& MultiIndex<Indices...>::operator+=(int n)
|
||||
{
|
||||
setPos( pos() + n );
|
||||
plus(*this, 0, n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
MultiIndex& MultiIndex<Indices...>::operator-=(int n)
|
||||
{
|
||||
setPos( pos() - n );
|
||||
plus(*this, 0, 0-n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
size_t MultiIndex<Indices...>::evaluate(const MultiIndex<Indices...>& in) const
|
||||
{
|
||||
return evaluate_x<sizeof...(Indices)-1>(in);
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
size_t MultiIndex<Indices...>::dim() const
|
||||
{
|
||||
size_t res = 1;
|
||||
for(size_t i = 0; i != sMult; ++i){
|
||||
res *= getIndex(i).dim();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
bool MultiIndex<Indices...>::link(IndefinitIndexBase* toLink)
|
||||
{
|
||||
if(toLink->rangeType() != rangeType() and toLink->name() == name()){
|
||||
// throw !!
|
||||
}
|
||||
|
||||
if(toLink->rangeType() == rangeType() and toLink->name() == name()){
|
||||
if(mLinked == toLink){
|
||||
return true; // dont link twice the same
|
||||
}
|
||||
else if(mLinked == nullptr){
|
||||
mLinked = toLink;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return mLinked->link(toLink);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return linkLower(toLink);
|
||||
}
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
auto& getIndex() -> decltype(std::get<N>(mIPack))
|
||||
{
|
||||
return std::get<N>(mIPack);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
const auto& getIndex() const -> decltype(std::get<N>(mIPack));
|
||||
{
|
||||
return std::get<N>(mIPack);
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
IndefinitIndexBase& MultiIndex<Indices...>::getIndex(size_t n)
|
||||
{
|
||||
if(n >= sMult){
|
||||
// throw !!
|
||||
}
|
||||
MultiIndex<Indices...>* t = this;
|
||||
return getIndex<sizeof...(Indices)>(*t, n);
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
const IndefinitIndexBase& MultiIndex<Indices...>::getIndex(size_t n) const
|
||||
{
|
||||
if(n >= sMult){
|
||||
// throw !!
|
||||
}
|
||||
MultiIndex<Indices...>* t = this;
|
||||
return getIndex<sizeof...(Indices)>(*t, n);
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
bool MultiIndex<Indices...>::linkLower(IndefinitIndexBase* toLink)
|
||||
{
|
||||
bool res = false;
|
||||
for(size_t i = 0; i != sMult; ++i){
|
||||
res |= getIndex(i).link(toLink);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
void MultiIndex<Indices...>::linkTo(IndefinitIndexBase* target)
|
||||
{
|
||||
target->link(this);
|
||||
for(size_t i = 0; i != sMult; ++i){
|
||||
getIndex(i).linkTo(target);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************
|
||||
* MultiArray *
|
||||
*******************/
|
||||
|
||||
template <typename... Ranges>
|
||||
void giveNames(const std::string& name, /**/);
|
||||
|
||||
template <typename... Ranges>
|
||||
void giveNames(const std::vector<std::string>& names, /**/);
|
||||
|
||||
/*!!!! giveNames(...) !!!!!*/
|
||||
|
||||
template <typename T, class Range>
|
||||
T& MultiArray<T,Is...>::operator()(const typename Range::indexType& i)
|
||||
{
|
||||
return mCont[ i.pos() ];
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
const T& MultiArray<T,Is...>::operator()(const typename Range::indexType& i) const
|
||||
{
|
||||
return mCont[ i.pos() ];
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
template <class... NameTypes>
|
||||
MultiArrayOperation<T,Range>& operator()(const NameTypes&... str) const
|
||||
{
|
||||
auto index = mRange->begin();
|
||||
// give names... !!!
|
||||
return MultiArrayOperation<T,Range>(*this, index);
|
||||
}
|
||||
|
||||
|
||||
/*********************************
|
||||
* MultiArrayOperationBase *
|
||||
*********************************/
|
||||
|
||||
template <typename T, class Range>
|
||||
template <class Range2>
|
||||
MultiArrayOperationBase<T,Range>&
|
||||
MultiArrayOperationBase<T,Range>::operator=(const MultiArrayOperationBase<T, Range2>& in)
|
||||
{
|
||||
in.linkIndicesTo(mIibPtr);
|
||||
for(*mIibPtr = mArrayRef.begin(); *mIibPtr != mArrayRef.end(); ++(*mIibPtr)){
|
||||
// build in vectorization later
|
||||
get() = in.get();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
template <class Operation, class... Ranges>
|
||||
MultiArrayOperation<Operation>
|
||||
MultiArrayOperationBase<T,Range>::operator()(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs)
|
||||
{
|
||||
return MultiArrayOperationBase<T,Range>(op, secs);
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
size_t MultiArrayOperationBase<T,Range>::argNum() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
IndefinitIndexBase* MultiArrayOperationBase<T,Range>::index()
|
||||
{
|
||||
return mIibPtr;
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
void MultiArrayOperationBase<T,Range>::linkIndicesTo(IndefinitIndexBase* target)
|
||||
{
|
||||
mIibPtr->linkTo(target);
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
T& MultiArrayOperationBase<T,Range>::get()
|
||||
{
|
||||
return mArrayRef(*mIibPtr);
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
const T& MultiArrayOperationBase<T,Range>::get() const
|
||||
{
|
||||
return mArrayRef(*mIibPtr);
|
||||
}
|
||||
|
||||
/*****************************
|
||||
* MultiArrayOperation *
|
||||
*****************************/
|
||||
|
||||
template <class IndexTuple, size_t N>
|
||||
void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target)
|
||||
{
|
||||
std::get<N>(itp).linkTo(target);
|
||||
linkTupleIndicesTo<N-1>(itp, target);
|
||||
}
|
||||
|
||||
template <class IndexTuple>
|
||||
void linkTupleIndicesTo<0>(IndexTuple& itp, IndefinitIndexBase* target)
|
||||
{
|
||||
std::get<0>(itp).linkTo(target);
|
||||
}
|
||||
|
||||
template <size_t N, class Operation, class Tuple, class... MBases>
|
||||
auto callOperation(Operation& op, Tuple& tp, MBases&... secs)
|
||||
-> decltype(callOperation(op, tp, std::get<N-1>(tp), secs...))
|
||||
{
|
||||
return callOperation(op, tp, std::get<N-1>(tp), secs...);
|
||||
}
|
||||
|
||||
template <class Operation, class Tuple, class... MBases>
|
||||
auto callOperation<0>(Operation& op, Tuple& tp, MBases&... secs) -> decltype(op(secs.get()...))
|
||||
{
|
||||
return op(secs.get()...);
|
||||
}
|
||||
|
||||
template <typename T, class Range, class Operation, class... Ranges>
|
||||
size_t MultiArrayOperation<T,Range,Operation,Ranges...>::argNum() const
|
||||
{
|
||||
return sizeof...(Ranges) + 1;
|
||||
}
|
||||
|
||||
template <typename T, class Range, class Operation, class... Ranges>
|
||||
void MultiArrayOperation<T,Range,Operation,Ranges...>::linkIndicesTo(IndefinitIndexBase* target)
|
||||
{
|
||||
mIibPtr->linkTo(target);
|
||||
linkTupleIndicesTo<sizeof...(Ranges)>(mSecs, target);
|
||||
}
|
||||
|
||||
template <typename T, class Range, class Operation, class... Ranges>
|
||||
T& MultiArrayOperation<T,Range,Operation,Ranges...>::get()
|
||||
{
|
||||
mVal = callOperation<sizeof...(Ranges)>(mOp, mSecs);
|
||||
return mVal;
|
||||
}
|
||||
|
||||
template <typename T, class Range, class Operation, class... Ranges>
|
||||
const T& MultiArrayOperation<T,Range,Operation,Ranges...>::get() const
|
||||
{
|
||||
mVal = callOperation<sizeof...(Ranges)>(mOp, mSecs);
|
||||
return mVal;
|
||||
}
|
||||
|
||||
} // end namespace ME
|
||||
|
39
src/multi_array.cc
Normal file
39
src/multi_array.cc
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
#include "multi_array.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
/*******************
|
||||
* MultiArray *
|
||||
*******************/
|
||||
|
||||
template <typename... Ranges>
|
||||
void giveNames(const std::string& name, /**/);
|
||||
|
||||
template <typename... Ranges>
|
||||
void giveNames(const std::vector<std::string>& names, /**/);
|
||||
|
||||
/*!!!! giveNames(...) !!!!!*/
|
||||
|
||||
template <typename T, class Range>
|
||||
T& MultiArray<T,Is...>::operator()(const typename Range::indexType& i)
|
||||
{
|
||||
return mCont[ i.pos() ];
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
const T& MultiArray<T,Is...>::operator()(const typename Range::indexType& i) const
|
||||
{
|
||||
return mCont[ i.pos() ];
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
template <class... NameTypes>
|
||||
MultiArrayOperation<T,Range>& operator()(const NameTypes&... str) const
|
||||
{
|
||||
auto index = mRange->begin();
|
||||
// give names... !!!
|
||||
return MultiArrayOperation<T,Range>(*this, index);
|
||||
}
|
||||
|
||||
}
|
117
src/multi_array_operation.cc
Normal file
117
src/multi_array_operation.cc
Normal file
|
@ -0,0 +1,117 @@
|
|||
|
||||
#include "mutli_array_operation.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
/*********************************
|
||||
* MultiArrayOperationBase *
|
||||
*********************************/
|
||||
|
||||
template <typename T, class Range>
|
||||
template <class Range2>
|
||||
MultiArrayOperationBase<T,Range>&
|
||||
MultiArrayOperationBase<T,Range>::operator=(const MultiArrayOperationBase<T, Range2>& in)
|
||||
{
|
||||
in.linkIndicesTo(mIibPtr);
|
||||
for(*mIibPtr = mArrayRef.begin(); *mIibPtr != mArrayRef.end(); ++(*mIibPtr)){
|
||||
// build in vectorization later
|
||||
get() = in.get();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
template <class Operation, class... Ranges>
|
||||
MultiArrayOperation<Operation>
|
||||
MultiArrayOperationBase<T,Range>::operator()(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs)
|
||||
{
|
||||
return MultiArrayOperationBase<T,Range>(op, secs);
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
size_t MultiArrayOperationBase<T,Range>::argNum() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
IndefinitIndexBase* MultiArrayOperationBase<T,Range>::index()
|
||||
{
|
||||
return mIibPtr;
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
void MultiArrayOperationBase<T,Range>::linkIndicesTo(IndefinitIndexBase* target)
|
||||
{
|
||||
mIibPtr->linkTo(target);
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
T& MultiArrayOperationBase<T,Range>::get()
|
||||
{
|
||||
return mArrayRef(*mIibPtr);
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
const T& MultiArrayOperationBase<T,Range>::get() const
|
||||
{
|
||||
return mArrayRef(*mIibPtr);
|
||||
}
|
||||
|
||||
/*****************************
|
||||
* MultiArrayOperation *
|
||||
*****************************/
|
||||
|
||||
template <class IndexTuple, size_t N>
|
||||
void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target)
|
||||
{
|
||||
std::get<N>(itp).linkTo(target);
|
||||
linkTupleIndicesTo<N-1>(itp, target);
|
||||
}
|
||||
|
||||
template <class IndexTuple>
|
||||
void linkTupleIndicesTo<0>(IndexTuple& itp, IndefinitIndexBase* target)
|
||||
{
|
||||
std::get<0>(itp).linkTo(target);
|
||||
}
|
||||
|
||||
template <size_t N, class Operation, class Tuple, class... MBases>
|
||||
auto callOperation(Operation& op, Tuple& tp, MBases&... secs)
|
||||
-> decltype(callOperation(op, tp, std::get<N-1>(tp), secs...))
|
||||
{
|
||||
return callOperation(op, tp, std::get<N-1>(tp), secs...);
|
||||
}
|
||||
|
||||
template <class Operation, class Tuple, class... MBases>
|
||||
auto callOperation<0>(Operation& op, Tuple& tp, MBases&... secs) -> decltype(op(secs.get()...))
|
||||
{
|
||||
return op(secs.get()...);
|
||||
}
|
||||
|
||||
template <typename T, class Range, class Operation, class... Ranges>
|
||||
size_t MultiArrayOperation<T,Range,Operation,Ranges...>::argNum() const
|
||||
{
|
||||
return sizeof...(Ranges) + 1;
|
||||
}
|
||||
|
||||
template <typename T, class Range, class Operation, class... Ranges>
|
||||
void MultiArrayOperation<T,Range,Operation,Ranges...>::linkIndicesTo(IndefinitIndexBase* target)
|
||||
{
|
||||
mIibPtr->linkTo(target);
|
||||
linkTupleIndicesTo<sizeof...(Ranges)>(mSecs, target);
|
||||
}
|
||||
|
||||
template <typename T, class Range, class Operation, class... Ranges>
|
||||
T& MultiArrayOperation<T,Range,Operation,Ranges...>::get()
|
||||
{
|
||||
mVal = callOperation<sizeof...(Ranges)>(mOp, mSecs);
|
||||
return mVal;
|
||||
}
|
||||
|
||||
template <typename T, class Range, class Operation, class... Ranges>
|
||||
const T& MultiArrayOperation<T,Range,Operation,Ranges...>::get() const
|
||||
{
|
||||
mVal = callOperation<sizeof...(Ranges)>(mOp, mSecs);
|
||||
return mVal;
|
||||
}
|
||||
|
||||
}
|
191
src/multi_range.cc
Normal file
191
src/multi_range.cc
Normal file
|
@ -0,0 +1,191 @@
|
|||
|
||||
#include "mutli_range.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
/*******************
|
||||
* MultiIndexBase *
|
||||
*******************/
|
||||
|
||||
namespace
|
||||
{
|
||||
template <class MultiIndex, size_t N>
|
||||
IndefinitIndexBase& getIndex(MultiIndex& in, size_t n)
|
||||
{
|
||||
if(n == N){
|
||||
return in.getIndex<N>();
|
||||
}
|
||||
else {
|
||||
return getIndex<N-1>(in, n);
|
||||
}
|
||||
}
|
||||
|
||||
template <class MultiIndex>
|
||||
IndefinitIndexBase& getIndex<MultiIndex,0>(MultiIndex& in, size_t n)
|
||||
{
|
||||
return in.getIndex<0>();
|
||||
}
|
||||
|
||||
template <size_t N, class MultiIndex>
|
||||
size_t evaluate_x(const MultiIndex& index)
|
||||
{
|
||||
const auto& subIndex = index.getIndex<N>();
|
||||
return evaluate_x<N-1>(index) * subIndex.size() + subIndex.pos();
|
||||
}
|
||||
|
||||
template <class MultiIndex>
|
||||
size_t evaluate_x<0>(const MultiIndex& index)
|
||||
{
|
||||
const auto& subIndex = index.getIndex<0>();
|
||||
return subIndex.pos();
|
||||
}
|
||||
|
||||
template <class MultiIndex>
|
||||
inline void plus(MultiIndex& index, size_t digit, int num)
|
||||
{
|
||||
IndefinitIndexBase& si = index.getIndex(digit);
|
||||
si.setPos( si.pos() + num );
|
||||
size_t oor = si.outOfRange();
|
||||
if(oor and digit != MultiIndex::mult - 1){
|
||||
plus(index, digit + 1, 1);
|
||||
plus(index, digit, oor - max());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class... Indices>
|
||||
MultiIndex& MultiIndex<Indices...>::operator++()
|
||||
{
|
||||
setPos( pos() + 1 );
|
||||
plus(*this, 0, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
MultiIndex& MultiIndex<Indices...>::operator--()
|
||||
{
|
||||
setPos( pos() - 1 );
|
||||
plus(*this, 0, -1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
MultiIndex& MultiIndex<Indices...>::operator+=(int n)
|
||||
{
|
||||
setPos( pos() + n );
|
||||
plus(*this, 0, n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
MultiIndex& MultiIndex<Indices...>::operator-=(int n)
|
||||
{
|
||||
setPos( pos() - n );
|
||||
plus(*this, 0, 0-n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
size_t MultiIndex<Indices...>::evaluate(const MultiIndex<Indices...>& in) const
|
||||
{
|
||||
return evaluate_x<sizeof...(Indices)-1>(in);
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
size_t MultiIndex<Indices...>::dim() const
|
||||
{
|
||||
size_t res = 1;
|
||||
for(size_t i = 0; i != sMult; ++i){
|
||||
res *= getIndex(i).dim();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
bool MultiIndex<Indices...>::link(IndefinitIndexBase* toLink)
|
||||
{
|
||||
if(toLink->rangeType() != rangeType() and toLink->name() == name()){
|
||||
// throw !!
|
||||
}
|
||||
|
||||
if(toLink->rangeType() == rangeType() and toLink->name() == name()){
|
||||
if(mLinked == toLink){
|
||||
return true; // dont link twice the same
|
||||
}
|
||||
else if(mLinked == nullptr){
|
||||
mLinked = toLink;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return mLinked->link(toLink);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return linkLower(toLink);
|
||||
}
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
auto& MultiIndex<Indices...>::getIndex() -> decltype(std::get<N>(mIPack))
|
||||
{
|
||||
return std::get<N>(mIPack);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
const auto& MultiIndex<Indices...>::getIndex() const -> decltype(std::get<N>(mIPack));
|
||||
{
|
||||
return std::get<N>(mIPack);
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
IndefinitIndexBase& MultiIndex<Indices...>::getIndex(size_t n)
|
||||
{
|
||||
if(n >= sMult){
|
||||
// throw !!
|
||||
}
|
||||
MultiIndex<Indices...>* t = this;
|
||||
return getIndex<sizeof...(Indices)>(*t, n);
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
const IndefinitIndexBase& MultiIndex<Indices...>::getIndex(size_t n) const
|
||||
{
|
||||
if(n >= sMult){
|
||||
// throw !!
|
||||
}
|
||||
MultiIndex<Indices...>* t = this;
|
||||
return getIndex<sizeof...(Indices)>(*t, n);
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
bool MultiIndex<Indices...>::linkLower(IndefinitIndexBase* toLink)
|
||||
{
|
||||
bool res = false;
|
||||
for(size_t i = 0; i != sMult; ++i){
|
||||
res |= getIndex(i).link(toLink);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
void MultiIndex<Indices...>::linkTo(IndefinitIndexBase* target)
|
||||
{
|
||||
target->link(this);
|
||||
for(size_t i = 0; i != sMult; ++i){
|
||||
getIndex(i).linkTo(target);
|
||||
}
|
||||
}
|
||||
|
||||
/******************
|
||||
* MultiRange *
|
||||
******************/
|
||||
|
||||
template <size_t N>
|
||||
auto MultiRange<Ranges...>::get() -> decltype( std::get<N>(mSpace) )
|
||||
{
|
||||
return std::get<N>(mSpace);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -37,8 +37,8 @@ namespace MultiArrayTools
|
|||
IndefinitIndexBase& getIndex(size_t n);
|
||||
const IndefinitIndexBase& getIndex(size_t n) const;
|
||||
|
||||
// dimension of MultiRange
|
||||
virtual size_t dim() const override; // implement !!!
|
||||
// dimension of MultiRange; includes ALL degrees of freedom
|
||||
virtual size_t dim() const override;
|
||||
|
||||
virtual bool link(IndefinitIndexBase* toLink) override;
|
||||
virtual void linkTo(IndefinitIndexBase* target) override;
|
||||
|
|
93
src/range_base.cc
Normal file
93
src/range_base.cc
Normal file
|
@ -0,0 +1,93 @@
|
|||
|
||||
#include "range_base.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
/*********************
|
||||
* MultiRangeType *
|
||||
*********************/
|
||||
|
||||
MultiRangeType& MultiRangeType::operator=(RangeType& type)
|
||||
{
|
||||
setType(type);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultiRangeType& MultiRangeType::operator=(const std::vector<MultiRangeType>& multiType)
|
||||
{
|
||||
setMultiType(multiType);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultiRangeType& MultiRangeType::operator[](size_t num)
|
||||
{
|
||||
return mMultiType->at(num);
|
||||
}
|
||||
|
||||
const MultiRangeType& MultiRangeType::operator[](size_t num) const
|
||||
{
|
||||
return mMultiType->at(num);
|
||||
}
|
||||
|
||||
bool MultiRangeType::multi() const
|
||||
{
|
||||
return mType != nullptr;
|
||||
}
|
||||
|
||||
bool MultiRangeType::operator==(const MultiRangeType& in) const
|
||||
{
|
||||
if(multi()){
|
||||
return *mMultiType == *in.mMultiType;
|
||||
}
|
||||
else {
|
||||
return mType == in.mType;
|
||||
}
|
||||
}
|
||||
|
||||
bool MultiRangeType::operator!=(const MultiRangeType& in) const
|
||||
{
|
||||
if(multi()){
|
||||
return *mMultiType != *in.mMultiType;
|
||||
}
|
||||
else {
|
||||
return mType != in.mType;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiRangeType::setType(RangeType type)
|
||||
{
|
||||
mType = type;
|
||||
if(mMultiType != nullptr){
|
||||
delete mMultiType;
|
||||
}
|
||||
mMultiType = nullptr;
|
||||
}
|
||||
|
||||
void MultiRangeType::setMultiType(const std::vector<MultiRangeType>& multiType)
|
||||
{
|
||||
mMultiType = new std::vector<MultiRangeType>( multiType );
|
||||
mType = RangeType::NIL;
|
||||
}
|
||||
|
||||
/******************
|
||||
* RangeBase *
|
||||
******************/
|
||||
|
||||
template <class Index>
|
||||
bool RangeBase<Index>::isSubRange() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*********************
|
||||
* SubRangeBase *
|
||||
*********************/
|
||||
|
||||
template <class Index>
|
||||
bool SubRangeBase<Index>::isSubRange() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
59
src/single_range.cc
Normal file
59
src/single_range.cc
Normal file
|
@ -0,0 +1,59 @@
|
|||
|
||||
#include "single_range.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
/********************
|
||||
* SingleRange *
|
||||
********************/
|
||||
|
||||
template <typename U, RangeType TYPE>
|
||||
const U& SingleRange<U,TYPE>::get(size_t pos) const
|
||||
{
|
||||
return mSpace[pos];
|
||||
}
|
||||
|
||||
template <typename U, RangeType TYPE>
|
||||
size_t SingleRange<U,TYPE>::get(const U& metaPos) const
|
||||
{
|
||||
size_t cnt = 0;
|
||||
for(auto& x: mSpace){
|
||||
if(x == metaPos){
|
||||
return cnt;
|
||||
}
|
||||
++cnt;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************
|
||||
* SingleIndex *
|
||||
******************/
|
||||
|
||||
template <typename U, IndexType TYPE>
|
||||
const U& SingleIndexBase<U,TYPE>::getMetaPos() const
|
||||
{
|
||||
return dynamic_cast<SingleRange*>( mRange )->get(mPos);
|
||||
}
|
||||
|
||||
template <typename U, IndexType TYPE>
|
||||
size_t dim() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <typename U, IndexType TYPE>
|
||||
size_t SingleIndexBase<TYPE>::evaluate(const Index& in)
|
||||
{
|
||||
return in.mPos;
|
||||
}
|
||||
|
||||
template <typename U, IndexType TYPE>
|
||||
void linkTo(IndefinitIndexBase* target)
|
||||
{
|
||||
target->link(this);
|
||||
}
|
||||
|
||||
}
|
46
src/tuple_helper.cc
Normal file
46
src/tuple_helper.cc
Normal file
|
@ -0,0 +1,46 @@
|
|||
|
||||
#include "tuple_helper.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
template <class Tuple, size_t N>
|
||||
auto make_left_x(const Tuple& tp) -> decltype(std::tuple_cat(make_left<Tuple,N-1>(tp),
|
||||
std::make_tuple(get<N>(tp))))
|
||||
{
|
||||
return std::tuple_cat(make_left<Tuple,N-1>(tp), std::make_tuple(get<N>(tp)));
|
||||
}
|
||||
|
||||
template <class Tuple>
|
||||
auto make_left_x<Tuple, 0>(const Tuple& tp) -> decltype(std::make_tuple(get<N>(tp)))
|
||||
{
|
||||
return std::make_tuple(get<N>(tp));
|
||||
}
|
||||
|
||||
template <class Tuple, size_t N>
|
||||
auto make_right_x(const Tuple& tp) -> decltype(std::tuple_cat(std::make_tuple(get<std::tuple_size(tp)-N>(tp)),
|
||||
make_left<Tuple,std::tuple_size(tp)-N+1>(tp)))
|
||||
{
|
||||
const size_t M = std::tuple_size(tp) - N;
|
||||
return std::tuple_cat(std::make_tuple(get<M>(tp)), make_left<Tuple,M+1>(tp));
|
||||
}
|
||||
|
||||
template <class Tuple>
|
||||
auto make_right_x<Tuple, 0>(const Tuple& tp) -> decltype(std::make_tuple(get<std::tuple_size(tp)>(tp)))
|
||||
{
|
||||
const size_t M = std::tuple_size(tp);
|
||||
return std::make_tuple(get<M>(tp));
|
||||
}
|
||||
|
||||
template <class Tuple, size_t N>
|
||||
auto make_left(const Tuple& tp) -> decltype(make_left_x<Tuple, N>(tp))
|
||||
{
|
||||
return make_left_x<Tuple, N>(tp);
|
||||
}
|
||||
|
||||
template <class Tuple, size_t N>
|
||||
auto make_right(const Tuple& tp) -> decltype(make_right_x<Tuple, std::tuple_size(Tuple)-N>(tp))
|
||||
{
|
||||
return make_right_x<Tuple, std::tuple_size(Tuple)-N>(tp);
|
||||
}
|
||||
}
|
|
@ -14,44 +14,23 @@ namespace MultiArrayTools
|
|||
|
||||
template <class Tuple, size_t N>
|
||||
auto make_left_x(const Tuple& tp) -> decltype(std::tuple_cat(make_left<Tuple,N-1>(tp),
|
||||
std::make_tuple(get<N>(tp))))
|
||||
{
|
||||
return std::tuple_cat(make_left<Tuple,N-1>(tp), std::make_tuple(get<N>(tp)));
|
||||
}
|
||||
std::make_tuple(get<N>(tp))));
|
||||
|
||||
template <class Tuple>
|
||||
auto make_left_x<Tuple, 0>(const Tuple& tp) -> decltype(std::make_tuple(get<N>(tp)))
|
||||
{
|
||||
return std::make_tuple(get<N>(tp));
|
||||
}
|
||||
auto make_left_x<Tuple, 0>(const Tuple& tp) -> decltype(std::make_tuple(get<N>(tp)));
|
||||
|
||||
template <class Tuple, size_t N>
|
||||
auto make_right_x(const Tuple& tp) -> decltype(std::tuple_cat(std::make_tuple(get<std::tuple_size(tp)-N>(tp)),
|
||||
make_left<Tuple,std::tuple_size(tp)-N+1>(tp)))
|
||||
{
|
||||
const size_t M = std::tuple_size(tp) - N;
|
||||
return std::tuple_cat(std::make_tuple(get<M>(tp)), make_left<Tuple,M+1>(tp));
|
||||
}
|
||||
make_left<Tuple,std::tuple_size(tp)-N+1>(tp)));
|
||||
|
||||
template <class Tuple>
|
||||
auto make_right_x<Tuple, 0>(const Tuple& tp) -> decltype(std::make_tuple(get<std::tuple_size(tp)>(tp)))
|
||||
{
|
||||
const size_t M = std::tuple_size(tp);
|
||||
return std::make_tuple(get<M>(tp));
|
||||
}
|
||||
auto make_right_x<Tuple, 0>(const Tuple& tp) -> decltype(std::make_tuple(get<std::tuple_size(tp)>(tp)));
|
||||
|
||||
template <class Tuple, size_t N>
|
||||
auto make_left(const Tuple& tp) -> decltype(make_left_x<Tuple, N>(tp))
|
||||
{
|
||||
return make_left_x<Tuple, N>(tp);
|
||||
}
|
||||
auto make_left(const Tuple& tp) -> decltype(make_left_x<Tuple, N>(tp));
|
||||
|
||||
template <class Tuple, size_t N>
|
||||
auto make_right(const Tuple& tp) -> decltype(make_right_x<Tuple, std::tuple_size(Tuple)-N>(tp))
|
||||
{
|
||||
return make_right_x<Tuple, std::tuple_size(Tuple)-N>(tp);
|
||||
}
|
||||
|
||||
auto make_right(const Tuple& tp) -> decltype(make_right_x<Tuple, std::tuple_size(Tuple)-N>(tp));
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue