#ifndef __helper_tools_h__ #define __helper_tools_h__ #include "base_def.h" #include "slice.h" namespace MultiArrayTools { template auto getIndex(std::shared_ptr range) -> std::shared_ptr; // only if 'RangeType' is defaultable and unique (Singleton) template auto getIndex() -> std::shared_ptr; template auto mkMulti(std::shared_ptr... ranges) -> std::shared_ptr >; template auto mkMIndex(std::shared_ptr... indices) -> decltype( getIndex( mkMulti( indices.range()... ) ) ); template auto mkMulti(std::tuple...> rangesTuple) -> MultiRange; } /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace MultiArrayTools { template auto getIndex(std::shared_ptr range) -> std::shared_ptr { return std::make_shared(range); } template auto getIndex() -> std::shared_ptr { static_assert( RangeType::defaultable, /*typeid(typename RangeType).name() + */" is not defaultable" ); static auto f = RangeType::factory(); static auto r = std::dynamic_pointer_cast( f.create() ); return std::make_shared(r); } template auto mkMulti(std::shared_ptr... ranges) -> std::shared_ptr > { MultiRangeFactory mrf( ranges... ); return std::dynamic_pointer_cast >( mrf.create() ); } template auto mkMIndex(std::shared_ptr... indices) -> decltype( getIndex( mkMulti( indices->range()... ) ) ) { auto mi = getIndex( mkMulti( indices->range()... ) ); (*mi)( indices... ); return mi; } template auto mkMulti(std::tuple...> rangesTuple) -> MultiRange { MultiRangeFactory mrf( rangesTuple ); return std::dynamic_pointer_cast >( mrf.create() ); } } #endif