#include "cxz_array.h" #include "statics/static_for.h" namespace MultiArrayTools { template Scalar scalar(const T& in) { NullRF nrf; return Scalar( std::dynamic_pointer_cast( nrf.create() ), vector( { in } ) ); } /******************* * MultiArray * *******************/ template MultiArray::MultiArray(const typename CRange::Space& space) : MutableMultiArrayBase(space), mCont(MAB::mRange->size()) { MAB::mInit = true; } template MultiArray::MultiArray(const typename CRange::Space& space, const vector& vec) : MutableMultiArrayBase(space), mCont(vec) { MAB::mInit = true; if(mCont.size() > MAB::mRange->size()){ mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end()); } } template MultiArray::MultiArray(const std::shared_ptr&... ranges) : MutableMultiArrayBase(ranges...), mCont(MAB::mRange->size()) { MAB::mInit = true; } template MultiArray::MultiArray(const std::shared_ptr&... ranges, const T& val) : MutableMultiArrayBase(ranges...), mCont(MAB::mRange->size(), val) { MAB::mInit = true; } template MultiArray::MultiArray(const std::shared_ptr&... ranges, const vector& vec) : MutableMultiArrayBase(ranges...), mCont(vec) { MAB::mInit = true; if(mCont.size() > MAB::mRange->size()){ mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end()); } } template MultiArray::MultiArray(const std::shared_ptr&... ranges, vector&& vec) : MutableMultiArrayBase(ranges...), mCont(std::forward>(vec)) { MAB::mInit = true; if(mCont.size() > MAB::mRange->size()){ mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end()); } } template template MultiArray::MultiArray(const std::shared_ptr&... ranges, MultiArray&& in) : MutableMultiArrayBase(ranges...), mCont( std::move( in.mCont ) ) { // maybe some checks here in the future... assert(mCont.size() == MAB::mRange->size()); MAB::mInit = true; in.mInit = false; } template MultiArray::MultiArray(MultiArray&& ama, SIZET... sizes) : MutableMultiArrayBase ( ama.range()->template get<0>().template scast(sizes...)->space() ), mCont( std::move( ama.mCont ) ) { MAB::mInit = true; ama.mInit = false; } template T& MultiArray::operator[](const IndexType& i) { return mCont[ i.pos() ]; } template const T& MultiArray::operator[](const IndexType& i) const { return mCont[ i.pos() ]; } template T& MultiArray::at(const typename IndexType::MetaType& meta) { return mCont[ MAB::cbegin().at(meta).pos() ]; } template const T& MultiArray::at(const typename IndexType::MetaType& meta) const { return mCont[ MAB::cbegin().at(meta).pos() ]; } template bool MultiArray::isConst() const { return false; } template bool MultiArray::isSlice() const { return false; } template template MultiArray MultiArray::format(const std::shared_ptr&... nrs) { //MAB::mInit = false; return MultiArray( nrs... , mCont ); } template template MultiArray MultiArray::format(const std::tuple...>& nrs) { //MAB::mInit = false; return MultiArray( nrs , mCont ); } template template Slice MultiArray::slformat(const std::shared_ptr&... nrs) { return Slice( nrs..., mCont.data() ); } template template ConstSlice MultiArray::slformat(const std::shared_ptr&... nrs) const { return ConstSlice( nrs..., mCont.data() ); } template const T* MultiArray::data() const { return mCont.data(); } template T* MultiArray::data() { return mCont.data(); } template std::shared_ptr > MultiArray::anonymous(bool slice) const { AnonymousRangeFactory arf(MAB::mRange->space()); if(slice){ return std::make_shared > ( std::dynamic_pointer_cast( arf.create() ), data() ); } else { return std::make_shared > ( std::dynamic_pointer_cast( arf.create() ), mCont ); } } template MultiArray& MultiArray::operator=(const T& in) { for(auto& x: mCont){ x = in; } return *this; } template MultiArray& MultiArray::operator+=(const MultiArray& in) { if(not MAB::mInit){ // not initialized by default constructor !! (*this) = in; } else { sfor_p<0,sizeof...(SRanges),0> ( [&](auto i) { return std::get(MAB::mRange->space()).get() == std::get(in.mRange->space()).get(); }, [&](auto a, auto b) { return a and b; }); for(size_t i = 0; i != mCont.size(); ++i){ mCont[i] += in.mCont[i]; } } return *this; } template MultiArray& MultiArray::operator-=(const MultiArray& in) { if(not MAB::mInit){ // not initialized by default constructor !! (*this) = in; } else { sfor_p<0,sizeof...(SRanges),0> ( [&](auto i) { return std::get(MAB::mRange->space()).get() == std::get(in.mRange->space()).get(); }, [&](auto a, auto b) { return a and b; }); for(size_t i = 0; i != mCont.size(); ++i){ mCont[i] -= in.mCont[i]; } } return *this; } template MultiArray& MultiArray::operator*=(const T& in) { for(auto& x: mCont){ x *= in; } return *this; } template MultiArray& MultiArray::operator/=(const T& in) { for(auto& x: mCont){ x /= in; } return *this; } template MultiArray::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 auto MultiArray::cat() const -> decltype(ArrayCatter::cat(*this)) { return ArrayCatter::cat(*this); } }