diff --git a/src/include/multi_array.h b/src/include/multi_array.h index f975586..663d96f 100644 --- a/src/include/multi_array.h +++ b/src/include/multi_array.h @@ -7,6 +7,20 @@ namespace MultiArrayTools { + template + struct ArrayCatter; + + + template + struct ArrayCatter + { + template + static auto cat(const MultiArray& ma) + -> MultiArray + { + return ma; + } + }; template @@ -23,6 +37,7 @@ namespace MultiArrayTools MultiArray(const std::shared_ptr&... ranges, const std::vector& vec); MultiArray(const std::shared_ptr&... ranges, std::vector&& vec); MultiArray(const typename CRange::SpaceType& space); + MultiArray(const typename CRange::SpaceType& space, std::vector&& vec); // Only if ALL ranges have default extensions: //MultiArray(const std::vector& vec); @@ -51,18 +66,46 @@ namespace MultiArrayTools virtual const T* data() const override; virtual T* data() override; virtual std::vector& vdata() { return mCont; } + virtual const std::vector& vdata() const { return mCont; } + auto cat() const + -> decltype(ArrayCatter::cat(*this)); + operator T() const; template friend class MultiArray; private: + std::vector mCont; }; template using Scalar = MultiArray; + + template + struct ArrayCatter > + { + template + static auto cat(const MultiArray,Ranges...>& ma) + -> MultiArray + { + auto sma = *ma.begin(); + const size_t smas = sma.size(); + const size_t mas = ma.size(); + auto cr = ma.range()->cat(sma.range()); + std::vector ov; + ov.reserve(mas * smas); + + for(auto& x: ma){ + assert(x.size() == smas); + ov.insert(ov.end(), x.vdata().begin(), x.vdata().end()); + } + return MultiArray(cr->space(), std::move(ov)); + } + }; + } @@ -84,7 +127,20 @@ namespace MultiArrayTools { MAB::mInit = true; } - + + template + MultiArray::MultiArray(const typename CRange::SpaceType& space, + std::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...), @@ -206,6 +262,13 @@ namespace MultiArrayTools static_assert( sizeof...(SRanges) == 0, "try to cast non-scalar type into scalar" ); return mCont[0]; } + + template + auto MultiArray::cat() const + -> decltype(ArrayCatter::cat(*this)) + { + return ArrayCatter::cat(*this); + } } #endif diff --git a/src/include/multi_array_base.h b/src/include/multi_array_base.h index b0fc699..7ead45e 100644 --- a/src/include/multi_array_base.h +++ b/src/include/multi_array_base.h @@ -26,6 +26,13 @@ namespace MultiArrayTools typedef ContainerRange CRange; typedef ContainerIndex IndexType; + protected: + bool mInit = false; + std::shared_ptr mRange; + std::shared_ptr mProtoI; + + public: + DEFAULT_MEMBERS(MultiArrayBase); MultiArrayBase(const std::shared_ptr&... ranges); MultiArrayBase(const typename CRange::SpaceType& space); @@ -54,11 +61,11 @@ namespace MultiArrayTools operator()(std::shared_ptr&... inds) const; virtual bool isInit() const; + + template + auto getRangePtr() const + -> decltype(mRange->template getPtr()); - protected: - bool mInit = false; - std::shared_ptr mRange; - std::shared_ptr mProtoI; }; template @@ -193,6 +200,14 @@ namespace MultiArrayTools return mInit; } + template + template + auto MultiArrayBase::getRangePtr() const + -> decltype(mRange->template getPtr()) + { + return mRange->template getPtr(); + } + /****************************** * MutableMultiArrayBase * diff --git a/src/include/ranges/anonymous_range.h b/src/include/ranges/anonymous_range.h index d47999c..b573c44 100644 --- a/src/include/ranges/anonymous_range.h +++ b/src/include/ranges/anonymous_range.h @@ -27,6 +27,9 @@ namespace MultiArrayTools template AnonymousRangeFactory(std::shared_ptr... origs); + template + void append(std::shared_ptr r); + std::shared_ptr create(); }; @@ -56,6 +59,9 @@ namespace MultiArrayTools template std::shared_ptr fullsub(size_t num) const; + + template + MultiRange scast() const; // save cast friend AnonymousRangeFactory; @@ -99,6 +105,12 @@ namespace MultiArrayTools { mProd = std::shared_ptr( new AnonymousRange( origs... ) ); } + + template + void AnonymousRangeFactory::append(std::shared_ptr r) + { + std::dynamic_pointer_cast(mProd)->mOrig.push_back(r); + } /*********************** * AnonymousRange * @@ -128,6 +140,12 @@ namespace MultiArrayTools { return std::dynamic_pointer_cast( mOrig.at(num) ); } + + template + MultiRange AnonymousRange::scast() const + { + // !!!!!! + } /***************** * Functions * diff --git a/src/include/ranges/container_range.h b/src/include/ranges/container_range.h index 3a97024..844bcec 100644 --- a/src/include/ranges/container_range.h +++ b/src/include/ranges/container_range.h @@ -494,6 +494,7 @@ namespace MultiArrayTools (*this)++; } } + return *this; } template @@ -509,6 +510,7 @@ namespace MultiArrayTools (*this)--; } } + return *this; } template diff --git a/src/include/ranges/multi_range.h b/src/include/ranges/multi_range.h index 4fded25..8f0b964 100644 --- a/src/include/ranges/multi_range.h +++ b/src/include/ranges/multi_range.h @@ -176,6 +176,10 @@ namespace MultiArrayTools virtual IndexType begin() const final; virtual IndexType end() const final; + template + auto cat(const std::shared_ptr >& erange) + -> std::shared_ptr >; + friend MultiRangeFactory; static constexpr bool defaultable = false; @@ -510,6 +514,17 @@ namespace MultiArrayTools i = size(); return i; } + + template + template + auto MultiRange::cat(const std::shared_ptr >& erange) + -> std::shared_ptr > + { + auto crange = std::tuple_cat(mSpace, erange->space()); + MultiRangeFactory rf(crange); + return std::dynamic_pointer_cast >(rf.create()); + } + } #endif diff --git a/src/include/ranges/range_types/header.h b/src/include/ranges/range_types/header.h index 54ff304..9c1f66e 100644 --- a/src/include/ranges/range_types/header.h +++ b/src/include/ranges/range_types/header.h @@ -15,6 +15,7 @@ //#define __ranges_header__ #include "spin_range.h" +#include "space_range.h" #include "classic_range.h" #undef __ranges_header__ diff --git a/src/include/ranges/range_types/space_range.h b/src/include/ranges/range_types/space_range.h new file mode 100644 index 0000000..79f3c26 --- /dev/null +++ b/src/include/ranges/range_types/space_range.h @@ -0,0 +1,118 @@ + +#ifdef include_range_type +include_range_type(PSPACE,3) // Periodic 1dim space +#else + +#ifdef __ranges_header__ + +namespace MultiArrayTools +{ + // Periodic 1dim space + typedef SingleIndex XSpaceIndex; + + template <> + class SingleRangeFactory : public RangeFactoryBase + { + public: + + typedef SingleRange oType; + + SingleRangeFactory(size_t size = 0); + std::shared_ptr create(); + + }; + + template <> + class SingleRange : public RangeInterface + { + public: + typedef RangeBase RB; + typedef typename RangeInterface >::IndexType IndexType; + typedef SingleRange RangeType; + typedef int MetaType; + + virtual size_t size() const override; + virtual size_t dim() const override; + + int get(size_t pos) const; + size_t getMeta(int metaPos) const; + + virtual IndexType begin() const override; + virtual IndexType end() const override; + //virtual std::shared_ptr index() const override; + + friend SingleRangeFactory; + + static constexpr bool defaultable = true; + static constexpr size_t ISSTATIC = 0; + static constexpr size_t SIZE = -1; + static constexpr bool HASMETACONT = false; + + static SingleRangeFactory factory(size_t size = 0) + { return SingleRangeFactory(size); } + + protected: + + size_t mSize = 0; + + SingleRange() = default; + SingleRange(const SingleRange& in) = delete; + + SingleRange(size_t size); + }; + + typedef SingleRange PSpaceRange; + typedef SingleRangeFactory PSpaceRF; + + template + struct PromoteMSpaceRange + { + template + static auto mk(MultiRange) -> MultiRange; + + template + static auto mkf(MultiRangeFactory) -> MultiRangeFactory; + + }; + + template + struct CreateNDimSpaceRange + { + template + static auto mk() + -> decltype(PromoteMSpaceRange:: + template mk(CreateNDimSpaceRange:: + template mk())); + + template + static auto mkf() + -> decltype(PromoteMSpaceRange:: + template mkf(CreateNDimSpaceRange:: + template mkf())); + + }; + + template <> + struct CreateNDimSpaceRange<1> + { + template + static auto mk() + -> MultiRange; + + template + static auto mkf() + -> MultiRangeFactory; + + }; + + template + using MSpaceRange = decltype(CreateNDimSpaceRange::template mk()); + + template + using MSpaceRF = decltype(CreateNDimSpaceRange::template mkf()); +} + + +#endif // #ifdef __ranges_header__ + +#endif // #ifdef include_range_type diff --git a/src/include/ranges/rpack_num.h b/src/include/ranges/rpack_num.h index 3f23aff..06947e0 100644 --- a/src/include/ranges/rpack_num.h +++ b/src/include/ranges/rpack_num.h @@ -203,7 +203,7 @@ namespace MultiArrayHelper template static void RangesToVec(const std::tuple...>& rst, - std::vector v) + std::vector >& v) { v[N] = std::get(rst); RPackNum::RangesToVec(rst, v); @@ -387,7 +387,7 @@ namespace MultiArrayHelper template static void RangesToVec(const std::tuple...>& rst, - std::vector v) + std::vector >& v) { v[0] = std::get<0>(rst); } diff --git a/src/lib/ranges/anonymous_range.cc b/src/lib/ranges/anonymous_range.cc index 61271dc..911e6a2 100644 --- a/src/lib/ranges/anonymous_range.cc +++ b/src/lib/ranges/anonymous_range.cc @@ -6,10 +6,10 @@ namespace MultiArrayTools /****************************** * AnonymousRangeFactory * ******************************/ - + std::shared_ptr AnonymousRangeFactory::create() { - setSelf(); + //setSelf(); return mProd; } @@ -55,6 +55,7 @@ namespace MultiArrayTools return i; } + std::shared_ptr AnonymousRange::sub(size_t num) const { return mOrig.at(num); diff --git a/src/lib/ranges/range_types/classic_range.cc b/src/lib/ranges/range_types/classic_range.cc index 97038bb..82c2af6 100644 --- a/src/lib/ranges/range_types/classic_range.cc +++ b/src/lib/ranges/range_types/classic_range.cc @@ -62,17 +62,5 @@ namespace MultiArrayTools i = size(); return i; } - - // put this in the interface class !!! - /* - std::shared_ptr SingleRange::index() const - { - typedef IndexWrapper IW; - return std::make_shared - ( std::make_shared - ( std::dynamic_pointer_cast > - ( std::shared_ptr( RB::mThis ) ) ) ); - } - */ } diff --git a/src/lib/ranges/range_types/space_range.cc b/src/lib/ranges/range_types/space_range.cc new file mode 100644 index 0000000..48fd9d4 --- /dev/null +++ b/src/lib/ranges/range_types/space_range.cc @@ -0,0 +1,66 @@ + +#include "ranges/rheader.h" + +namespace MultiArrayTools +{ + /******************** + * SingleRange * + ********************/ + + SingleRangeFactory::SingleRangeFactory(size_t size) + { + // Quasi Singleton + if(not mProd){ + mProd = std::shared_ptr( new SingleRange(size) ); + setSelf(); + } + } + + std::shared_ptr SingleRangeFactory::create() + { + return mProd; + } + + /******************** + * SingleRange * + ********************/ + + SingleRange::SingleRange(size_t size) : mSize(size) { } + + int SingleRange::get(size_t pos) const + { + return pos > mSize / 2 ? pos - mSize : pos; + } + + size_t SingleRange::getMeta(int metaPos) const + { + return metaPos < 0 ? metaPos + mSize : metaPos; + } + + size_t SingleRange::size() const + { + return mSize; + } + + size_t SingleRange::dim() const + { + return 1; + } + + typename SingleRange::IndexType SingleRange::begin() const + { + SingleIndex i( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis ) ) ); + i = 0; + return i; + } + + typename SingleRange::IndexType SingleRange::end() const + { + SingleIndex i( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis ) ) ); + i = size(); + return i; + } +} +