diff --git a/src/index_base.cc b/src/index_base.cc new file mode 100644 index 0000000..c5ab5a4 --- /dev/null +++ b/src/index_base.cc @@ -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( -1 ); + } + + size_t IndefinitIndexBase::outOfRange() const + { + int res = pos() - max(); + return res > 0 ? static_cast(res) : 0; + } + + /************** + * IndexBase * + **************/ + + template + Index& IndexBase::operator=(const Index& in) + { + setPos( evaluate(in) ); + } + + template + Index& IndexBase::operator=(size_t pos) + { + setPos( pos ); + return *this; + } + + template + Index& IndexBase::operator++() + { + setPos( ++mPos ); + return *this; + } + + template + Index& IndexBase::operator--() + { + setPos( --mPos ); + return *this; + } + + template + Index& IndexBase::operator+=(int n) + { + setPos( mPos += n ); + return *this; + } + + template + Index& IndexBase::operator-=(int n) + { + setPos( mPos -= n ); + return *this; + } + + template + bool IndexBase::operator==(const Index& i) + { + return mRange == i.mRange and mPos == i.mPos; + } + + template + bool IndexBase::operator!=(const Index& i) + { + return mRange != i.mRange or mPos != i.mPos; + } + + template + size_t IndexBase::max() const + { + return mRange->size(); + } + + +} diff --git a/src/me.cc b/src/me.cc deleted file mode 100644 index 68558fb..0000000 --- a/src/me.cc +++ /dev/null @@ -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& 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& multiType) - { - mMultiType = new std::vector( multiType ); - mType = RangeType::NIL; - } - - /****************** - * RangeBase * - ******************/ - - template - bool RangeBase::isSubRange() const - { - return false; - } - - /********************* - * SubRangeBase * - *********************/ - - template - bool SubRangeBase::isSubRange() const - { - return true; - } - - /******************** - * SingleRange * - ********************/ - - template - const U& SingleRange::get(size_t pos) const - { - return mSpace[pos]; - } - - template - size_t SingleRange::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( -1 ); - } - - size_t IndefinitIndexBase::outOfRange() const - { - int res = pos() - max(); - return res > 0 ? static_cast(res) : 0; - } - - /************** - * IndexBase * - **************/ - - template - Index& IndexBase::operator=(const Index& in) - { - setPos( evaluate(in) ); - } - - template - Index& IndexBase::operator=(size_t pos) - { - setPos( pos ); - return *this; - } - - template - Index& IndexBase::operator++() - { - setPos( ++mPos ); - return *this; - } - - template - Index& IndexBase::operator--() - { - setPos( --mPos ); - return *this; - } - - template - Index& IndexBase::operator+=(int n) - { - setPos( mPos += n ); - return *this; - } - - template - Index& IndexBase::operator-=(int n) - { - setPos( mPos -= n ); - return *this; - } - - template - bool IndexBase::operator==(const Index& i) - { - return mRange == i.mRange and mPos == i.mPos; - } - - template - bool IndexBase::operator!=(const Index& i) - { - return mRange != i.mRange or mPos != i.mPos; - } - - template - size_t IndexBase::max() const - { - return mRange->size(); - } - - - /******************** - * SingleIndexBase * - ********************/ - - template - const U& SingleIndexBase::getMetaPos() const - { - return dynamic_cast( mRange )->get(mPos); - } - - template - size_t dim() const - { - return 1; - } - - template - size_t SingleIndexBase::evaluate(const Index& in) - { - return in.mPos; - } - - template - void linkTo(IndefinitIndexBase* target) - { - target->link(this); - } - - /******************* - * MultiIndexBase * - *******************/ - - namespace - { - template - IndefinitIndexBase& getIndex(MultiIndex& in, size_t n) - { - if(n == N){ - return in.getIndex(); - } - else { - return getIndex(in, n); - } - } - - template - IndefinitIndexBase& getIndex(MultiIndex& in, size_t n) - { - return in.getIndex<0>(); - } - - template - size_t evaluate_x(const MultiIndex& index) - { - const auto& subIndex = index.getIndex(); - return evaluate_x(index) * subIndex.size() + subIndex.pos(); - } - - template - size_t evaluate_x<0>(const MultiIndex& index) - { - const auto& subIndex = index.getIndex<0>(); - return subIndex.pos(); - } - - template - 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 - MultiIndex& MultiIndex::operator++() - { - setPos( pos() + 1 ); - plus(*this, 0, 1); - return *this; - } - - template - MultiIndex& MultiIndex::operator--() - { - setPos( pos() - 1 ); - plus(*this, 0, -1); - return *this; - } - - template - MultiIndex& MultiIndex::operator+=(int n) - { - setPos( pos() + n ); - plus(*this, 0, n); - return *this; - } - - template - MultiIndex& MultiIndex::operator-=(int n) - { - setPos( pos() - n ); - plus(*this, 0, 0-n); - return *this; - } - - template - size_t MultiIndex::evaluate(const MultiIndex& in) const - { - return evaluate_x(in); - } - - template - size_t MultiIndex::dim() const - { - size_t res = 1; - for(size_t i = 0; i != sMult; ++i){ - res *= getIndex(i).dim(); - } - return res; - } - - template - bool MultiIndex::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 - auto& getIndex() -> decltype(std::get(mIPack)) - { - return std::get(mIPack); - } - - template - const auto& getIndex() const -> decltype(std::get(mIPack)); - { - return std::get(mIPack); - } - - template - IndefinitIndexBase& MultiIndex::getIndex(size_t n) - { - if(n >= sMult){ - // throw !! - } - MultiIndex* t = this; - return getIndex(*t, n); - } - - template - const IndefinitIndexBase& MultiIndex::getIndex(size_t n) const - { - if(n >= sMult){ - // throw !! - } - MultiIndex* t = this; - return getIndex(*t, n); - } - - template - bool MultiIndex::linkLower(IndefinitIndexBase* toLink) - { - bool res = false; - for(size_t i = 0; i != sMult; ++i){ - res |= getIndex(i).link(toLink); - } - return res; - } - - template - void MultiIndex::linkTo(IndefinitIndexBase* target) - { - target->link(this); - for(size_t i = 0; i != sMult; ++i){ - getIndex(i).linkTo(target); - } - } - - /******************* - * MultiArray * - *******************/ - - template - void giveNames(const std::string& name, /**/); - - template - void giveNames(const std::vector& names, /**/); - - /*!!!! giveNames(...) !!!!!*/ - - template - T& MultiArray::operator()(const typename Range::indexType& i) - { - return mCont[ i.pos() ]; - } - - template - const T& MultiArray::operator()(const typename Range::indexType& i) const - { - return mCont[ i.pos() ]; - } - - template - template - MultiArrayOperation& operator()(const NameTypes&... str) const - { - auto index = mRange->begin(); - // give names... !!! - return MultiArrayOperation(*this, index); - } - - - /********************************* - * MultiArrayOperationBase * - *********************************/ - - template - template - MultiArrayOperationBase& - MultiArrayOperationBase::operator=(const MultiArrayOperationBase& in) - { - in.linkIndicesTo(mIibPtr); - for(*mIibPtr = mArrayRef.begin(); *mIibPtr != mArrayRef.end(); ++(*mIibPtr)){ - // build in vectorization later - get() = in.get(); - } - } - - template - template - MultiArrayOperation - MultiArrayOperationBase::operator()(Operation& op, MultiArrayOperationBase&... secs) - { - return MultiArrayOperationBase(op, secs); - } - - template - size_t MultiArrayOperationBase::argNum() const - { - return 1; - } - - template - IndefinitIndexBase* MultiArrayOperationBase::index() - { - return mIibPtr; - } - - template - void MultiArrayOperationBase::linkIndicesTo(IndefinitIndexBase* target) - { - mIibPtr->linkTo(target); - } - - template - T& MultiArrayOperationBase::get() - { - return mArrayRef(*mIibPtr); - } - - template - const T& MultiArrayOperationBase::get() const - { - return mArrayRef(*mIibPtr); - } - - /***************************** - * MultiArrayOperation * - *****************************/ - - template - void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target) - { - std::get(itp).linkTo(target); - linkTupleIndicesTo(itp, target); - } - - template - void linkTupleIndicesTo<0>(IndexTuple& itp, IndefinitIndexBase* target) - { - std::get<0>(itp).linkTo(target); - } - - template - auto callOperation(Operation& op, Tuple& tp, MBases&... secs) - -> decltype(callOperation(op, tp, std::get(tp), secs...)) - { - return callOperation(op, tp, std::get(tp), secs...); - } - - template - auto callOperation<0>(Operation& op, Tuple& tp, MBases&... secs) -> decltype(op(secs.get()...)) - { - return op(secs.get()...); - } - - template - size_t MultiArrayOperation::argNum() const - { - return sizeof...(Ranges) + 1; - } - - template - void MultiArrayOperation::linkIndicesTo(IndefinitIndexBase* target) - { - mIibPtr->linkTo(target); - linkTupleIndicesTo(mSecs, target); - } - - template - T& MultiArrayOperation::get() - { - mVal = callOperation(mOp, mSecs); - return mVal; - } - - template - const T& MultiArrayOperation::get() const - { - mVal = callOperation(mOp, mSecs); - return mVal; - } - -} // end namespace ME - diff --git a/src/multi_array.cc b/src/multi_array.cc new file mode 100644 index 0000000..b084ded --- /dev/null +++ b/src/multi_array.cc @@ -0,0 +1,39 @@ + +#include "multi_array.h" + +namespace MultiArrayTools +{ + /******************* + * MultiArray * + *******************/ + + template + void giveNames(const std::string& name, /**/); + + template + void giveNames(const std::vector& names, /**/); + + /*!!!! giveNames(...) !!!!!*/ + + template + T& MultiArray::operator()(const typename Range::indexType& i) + { + return mCont[ i.pos() ]; + } + + template + const T& MultiArray::operator()(const typename Range::indexType& i) const + { + return mCont[ i.pos() ]; + } + + template + template + MultiArrayOperation& operator()(const NameTypes&... str) const + { + auto index = mRange->begin(); + // give names... !!! + return MultiArrayOperation(*this, index); + } + +} diff --git a/src/multi_array_operation.cc b/src/multi_array_operation.cc new file mode 100644 index 0000000..a05fc72 --- /dev/null +++ b/src/multi_array_operation.cc @@ -0,0 +1,117 @@ + +#include "mutli_array_operation.h" + +namespace MultiArrayTools +{ + /********************************* + * MultiArrayOperationBase * + *********************************/ + + template + template + MultiArrayOperationBase& + MultiArrayOperationBase::operator=(const MultiArrayOperationBase& in) + { + in.linkIndicesTo(mIibPtr); + for(*mIibPtr = mArrayRef.begin(); *mIibPtr != mArrayRef.end(); ++(*mIibPtr)){ + // build in vectorization later + get() = in.get(); + } + } + + template + template + MultiArrayOperation + MultiArrayOperationBase::operator()(Operation& op, MultiArrayOperationBase&... secs) + { + return MultiArrayOperationBase(op, secs); + } + + template + size_t MultiArrayOperationBase::argNum() const + { + return 1; + } + + template + IndefinitIndexBase* MultiArrayOperationBase::index() + { + return mIibPtr; + } + + template + void MultiArrayOperationBase::linkIndicesTo(IndefinitIndexBase* target) + { + mIibPtr->linkTo(target); + } + + template + T& MultiArrayOperationBase::get() + { + return mArrayRef(*mIibPtr); + } + + template + const T& MultiArrayOperationBase::get() const + { + return mArrayRef(*mIibPtr); + } + + /***************************** + * MultiArrayOperation * + *****************************/ + + template + void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target) + { + std::get(itp).linkTo(target); + linkTupleIndicesTo(itp, target); + } + + template + void linkTupleIndicesTo<0>(IndexTuple& itp, IndefinitIndexBase* target) + { + std::get<0>(itp).linkTo(target); + } + + template + auto callOperation(Operation& op, Tuple& tp, MBases&... secs) + -> decltype(callOperation(op, tp, std::get(tp), secs...)) + { + return callOperation(op, tp, std::get(tp), secs...); + } + + template + auto callOperation<0>(Operation& op, Tuple& tp, MBases&... secs) -> decltype(op(secs.get()...)) + { + return op(secs.get()...); + } + + template + size_t MultiArrayOperation::argNum() const + { + return sizeof...(Ranges) + 1; + } + + template + void MultiArrayOperation::linkIndicesTo(IndefinitIndexBase* target) + { + mIibPtr->linkTo(target); + linkTupleIndicesTo(mSecs, target); + } + + template + T& MultiArrayOperation::get() + { + mVal = callOperation(mOp, mSecs); + return mVal; + } + + template + const T& MultiArrayOperation::get() const + { + mVal = callOperation(mOp, mSecs); + return mVal; + } + +} diff --git a/src/multi_range.cc b/src/multi_range.cc new file mode 100644 index 0000000..aa6254d --- /dev/null +++ b/src/multi_range.cc @@ -0,0 +1,191 @@ + +#include "mutli_range.h" + +namespace MultiArrayTools +{ + /******************* + * MultiIndexBase * + *******************/ + + namespace + { + template + IndefinitIndexBase& getIndex(MultiIndex& in, size_t n) + { + if(n == N){ + return in.getIndex(); + } + else { + return getIndex(in, n); + } + } + + template + IndefinitIndexBase& getIndex(MultiIndex& in, size_t n) + { + return in.getIndex<0>(); + } + + template + size_t evaluate_x(const MultiIndex& index) + { + const auto& subIndex = index.getIndex(); + return evaluate_x(index) * subIndex.size() + subIndex.pos(); + } + + template + size_t evaluate_x<0>(const MultiIndex& index) + { + const auto& subIndex = index.getIndex<0>(); + return subIndex.pos(); + } + + template + 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 + MultiIndex& MultiIndex::operator++() + { + setPos( pos() + 1 ); + plus(*this, 0, 1); + return *this; + } + + template + MultiIndex& MultiIndex::operator--() + { + setPos( pos() - 1 ); + plus(*this, 0, -1); + return *this; + } + + template + MultiIndex& MultiIndex::operator+=(int n) + { + setPos( pos() + n ); + plus(*this, 0, n); + return *this; + } + + template + MultiIndex& MultiIndex::operator-=(int n) + { + setPos( pos() - n ); + plus(*this, 0, 0-n); + return *this; + } + + template + size_t MultiIndex::evaluate(const MultiIndex& in) const + { + return evaluate_x(in); + } + + template + size_t MultiIndex::dim() const + { + size_t res = 1; + for(size_t i = 0; i != sMult; ++i){ + res *= getIndex(i).dim(); + } + return res; + } + + template + bool MultiIndex::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 + auto& MultiIndex::getIndex() -> decltype(std::get(mIPack)) + { + return std::get(mIPack); + } + + template + const auto& MultiIndex::getIndex() const -> decltype(std::get(mIPack)); + { + return std::get(mIPack); + } + + template + IndefinitIndexBase& MultiIndex::getIndex(size_t n) + { + if(n >= sMult){ + // throw !! + } + MultiIndex* t = this; + return getIndex(*t, n); + } + + template + const IndefinitIndexBase& MultiIndex::getIndex(size_t n) const + { + if(n >= sMult){ + // throw !! + } + MultiIndex* t = this; + return getIndex(*t, n); + } + + template + bool MultiIndex::linkLower(IndefinitIndexBase* toLink) + { + bool res = false; + for(size_t i = 0; i != sMult; ++i){ + res |= getIndex(i).link(toLink); + } + return res; + } + + template + void MultiIndex::linkTo(IndefinitIndexBase* target) + { + target->link(this); + for(size_t i = 0; i != sMult; ++i){ + getIndex(i).linkTo(target); + } + } + + /****************** + * MultiRange * + ******************/ + + template + auto MultiRange::get() -> decltype( std::get(mSpace) ) + { + return std::get(mSpace); + } + + +} diff --git a/src/multi_range.h b/src/multi_range.h index 5871a0a..3bbd1e7 100644 --- a/src/multi_range.h +++ b/src/multi_range.h @@ -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; diff --git a/src/range_base.cc b/src/range_base.cc new file mode 100644 index 0000000..9bbecc0 --- /dev/null +++ b/src/range_base.cc @@ -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& 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& multiType) + { + mMultiType = new std::vector( multiType ); + mType = RangeType::NIL; + } + + /****************** + * RangeBase * + ******************/ + + template + bool RangeBase::isSubRange() const + { + return false; + } + + /********************* + * SubRangeBase * + *********************/ + + template + bool SubRangeBase::isSubRange() const + { + return true; + } + + +} diff --git a/src/single_range.cc b/src/single_range.cc new file mode 100644 index 0000000..7013592 --- /dev/null +++ b/src/single_range.cc @@ -0,0 +1,59 @@ + +#include "single_range.h" + +namespace MultiArrayTools +{ + /******************** + * SingleRange * + ********************/ + + template + const U& SingleRange::get(size_t pos) const + { + return mSpace[pos]; + } + + template + size_t SingleRange::get(const U& metaPos) const + { + size_t cnt = 0; + for(auto& x: mSpace){ + if(x == metaPos){ + return cnt; + } + ++cnt; + } + return cnt; + } + + + + /****************** + * SingleIndex * + ******************/ + + template + const U& SingleIndexBase::getMetaPos() const + { + return dynamic_cast( mRange )->get(mPos); + } + + template + size_t dim() const + { + return 1; + } + + template + size_t SingleIndexBase::evaluate(const Index& in) + { + return in.mPos; + } + + template + void linkTo(IndefinitIndexBase* target) + { + target->link(this); + } + +} diff --git a/src/tuple_helper.cc b/src/tuple_helper.cc new file mode 100644 index 0000000..0055226 --- /dev/null +++ b/src/tuple_helper.cc @@ -0,0 +1,46 @@ + +#include "tuple_helper.h" + +namespace MultiArrayTools +{ + + template + auto make_left_x(const Tuple& tp) -> decltype(std::tuple_cat(make_left(tp), + std::make_tuple(get(tp)))) + { + return std::tuple_cat(make_left(tp), std::make_tuple(get(tp))); + } + + template + auto make_left_x(const Tuple& tp) -> decltype(std::make_tuple(get(tp))) + { + return std::make_tuple(get(tp)); + } + + template + auto make_right_x(const Tuple& tp) -> decltype(std::tuple_cat(std::make_tuple(get(tp)), + make_left(tp))) + { + const size_t M = std::tuple_size(tp) - N; + return std::tuple_cat(std::make_tuple(get(tp)), make_left(tp)); + } + + template + auto make_right_x(const Tuple& tp) -> decltype(std::make_tuple(get(tp))) + { + const size_t M = std::tuple_size(tp); + return std::make_tuple(get(tp)); + } + + template + auto make_left(const Tuple& tp) -> decltype(make_left_x(tp)) + { + return make_left_x(tp); + } + + template + auto make_right(const Tuple& tp) -> decltype(make_right_x(tp)) + { + return make_right_x(tp); + } +} diff --git a/src/tuple_helper.h b/src/tuple_helper.h index d3f99b0..dde29ce 100644 --- a/src/tuple_helper.h +++ b/src/tuple_helper.h @@ -14,44 +14,23 @@ namespace MultiArrayTools template auto make_left_x(const Tuple& tp) -> decltype(std::tuple_cat(make_left(tp), - std::make_tuple(get(tp)))) - { - return std::tuple_cat(make_left(tp), std::make_tuple(get(tp))); - } + std::make_tuple(get(tp)))); template - auto make_left_x(const Tuple& tp) -> decltype(std::make_tuple(get(tp))) - { - return std::make_tuple(get(tp)); - } - + auto make_left_x(const Tuple& tp) -> decltype(std::make_tuple(get(tp))); + template auto make_right_x(const Tuple& tp) -> decltype(std::tuple_cat(std::make_tuple(get(tp)), - make_left(tp))) - { - const size_t M = std::tuple_size(tp) - N; - return std::tuple_cat(std::make_tuple(get(tp)), make_left(tp)); - } - + make_left(tp))); + template - auto make_right_x(const Tuple& tp) -> decltype(std::make_tuple(get(tp))) - { - const size_t M = std::tuple_size(tp); - return std::make_tuple(get(tp)); - } + auto make_right_x(const Tuple& tp) -> decltype(std::make_tuple(get(tp))); template - auto make_left(const Tuple& tp) -> decltype(make_left_x(tp)) - { - return make_left_x(tp); - } + auto make_left(const Tuple& tp) -> decltype(make_left_x(tp)); template - auto make_right(const Tuple& tp) -> decltype(make_right_x(tp)) - { - return make_right_x(tp); - } - + auto make_right(const Tuple& tp) -> decltype(make_right_x(tp)); }