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