diff --git a/src/include/ranges/multi_range.h b/src/include/ranges/multi_range.h index 8f0b964..a86e99f 100644 --- a/src/include/ranges/multi_range.h +++ b/src/include/ranges/multi_range.h @@ -6,12 +6,14 @@ #include #include #include +#include //#include "base_def.h" #include "ranges/range_base.h" #include "ranges/index_base.h" -#include "rpack_num.h" +#include "ranges/rpack_num.h" +#include "ranges/multi_range_factory_product_map.h" namespace MultiArrayTools { @@ -118,6 +120,7 @@ namespace MultiArrayTools * MultiRangeFactory * *************************/ + // NOT THREAD SAVE template class MultiRangeFactory : public RangeFactoryBase { @@ -132,6 +135,11 @@ namespace MultiArrayTools MultiRangeFactory(const std::shared_ptr >& cr); virtual std::shared_ptr create() override; + + private: + + std::shared_ptr checkIfCreated(const std::tuple...>& ptp); + }; /****************** @@ -449,9 +457,33 @@ namespace MultiArrayTools template std::shared_ptr MultiRangeFactory::create() { + mProd = checkIfCreated( std::dynamic_pointer_cast( mProd )->mSpace ); setSelf(); return mProd; } + + template + std::shared_ptr MultiRangeFactory::checkIfCreated(const std::tuple...>& ptp) + { + std::shared_ptr out; + bool check = false; + for(auto& x: MultiRangeFactoryProductMap::mAleadyCreated){ + if(x.second.size() == sizeof...(Ranges)){ + check = RPackNum::checkIfCreated(ptp, x.second); + if(check){ + out = x.first; + break; + } + } + } + if(not check){ + std::vector pv(sizeof...(Ranges)); + RPackNum::RangesToVec(ptp, pv); + MultiRangeFactoryProductMap::mAleadyCreated[mProd] = pv; + out = mProd; + } + return out; + } /****************** * MultiRange * diff --git a/src/include/ranges/multi_range_factory_product_map.h b/src/include/ranges/multi_range_factory_product_map.h new file mode 100644 index 0000000..c6b10df --- /dev/null +++ b/src/include/ranges/multi_range_factory_product_map.h @@ -0,0 +1,25 @@ + +#ifndef __multi_range_factory_product_map_h__ +#define __multi_range_factory_product_map_h__ + +#include +#include +#include +#include "ranges/rbase_def.h" + +namespace MultiArrayTools +{ + class MultiRangeFactoryProductMap + { + public: + + template + friend class MultiRangeFactory; + + private: + static std::map,std::vector > mAleadyCreated; + }; + +} + +#endif diff --git a/src/include/ranges/rpack_num.h b/src/include/ranges/rpack_num.h index bfbc05d..c348e41 100644 --- a/src/include/ranges/rpack_num.h +++ b/src/include/ranges/rpack_num.h @@ -227,7 +227,14 @@ namespace MultiArrayHelper std::vector >& v) { setRangeToVec(v, std::get(rst)); - //v[N] = std::get(rst); + RPackNum::RangesToVec(rst, v); + } + + template + static inline void RangesToVec(const std::tuple...>& rst, + std::vector& v) + { + v[N] = reinterpret_cast( std::get(rst).get() ); RPackNum::RangesToVec(rst, v); } @@ -285,6 +292,14 @@ namespace MultiArrayHelper resolveSetRange(std::get(rtp), orig, off, size); RPackNum::resolveRangeType(orig, rtp, off+size, sizes...); } + + template + static inline bool checkIfCreated(const std::tuple...>& p, + const std::vector& a) + { + return reinterpret_cast( std::get(p).get() ) == a[N] and + RPackNum::checkIfCreated(p,a); + } }; @@ -416,6 +431,13 @@ namespace MultiArrayHelper return 1; } + template + static inline void RangesToVec(const std::tuple...>& rst, + std::vector& v) + { + v[0] = reinterpret_cast( std::get<0>(rst).get() );; + } + template static inline void RangesToVec(const std::tuple...>& rst, std::vector >& v) @@ -472,6 +494,13 @@ namespace MultiArrayHelper resolveSetRange(std::get(rtp), orig, off, size); } + template + static inline bool checkIfCreated(const std::tuple...>& p, + const std::vector& a) + { + return reinterpret_cast( std::get<0>(p).get() ) == a[0]; + } + }; template diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index bffe052..c2c6a05 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -2,6 +2,7 @@ set(libmultiarray_a_SOURCES ${CMAKE_SOURCE_DIR}/src/lib/ranges/range_base.cc ${CMAKE_SOURCE_DIR}/src/lib/ranges/anonymous_range.cc + ${CMAKE_SOURCE_DIR}/src/lib/ranges/multi_range_factory_product_map.cc ) file(GLOB cc_files "${CMAKE_SOURCE_DIR}/src/lib/ranges/range_types/*.cc") diff --git a/src/lib/ranges/multi_range_factory_product_map.cc b/src/lib/ranges/multi_range_factory_product_map.cc new file mode 100644 index 0000000..30da2dc --- /dev/null +++ b/src/lib/ranges/multi_range_factory_product_map.cc @@ -0,0 +1,7 @@ + +#include "ranges/multi_range_factory_product_map.h" + +namespace MultiArrayTools +{ + std::map,std::vector > MultiRangeFactoryProductMap::mAleadyCreated; +}