2018-02-16 18:17:22 +01:00
|
|
|
|
|
|
|
#ifndef __multi_array_base_h__
|
|
|
|
#define __multi_array_base_h__
|
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <vector>
|
|
|
|
#include <memory>
|
|
|
|
#include <iterator>
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
#include "base_def.h"
|
|
|
|
#include "mbase_def.h"
|
|
|
|
|
|
|
|
#include "ranges/rheader.h"
|
|
|
|
|
|
|
|
namespace MultiArrayTools
|
|
|
|
{
|
|
|
|
|
|
|
|
// Explicitely specify subranges in template argument !!!
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
class MultiArrayBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef T value_type;
|
|
|
|
typedef ContainerRange<T,SRanges...> CRange;
|
2018-03-01 18:16:12 +01:00
|
|
|
typedef ContainerIndex<T,typename SRanges::IndexType...> IndexType;
|
2018-02-16 18:17:22 +01:00
|
|
|
|
2018-05-20 20:03:44 +02:00
|
|
|
protected:
|
|
|
|
bool mInit = false;
|
|
|
|
std::shared_ptr<CRange> mRange;
|
|
|
|
std::shared_ptr<IndexType> mProtoI;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2018-02-16 18:17:22 +01:00
|
|
|
DEFAULT_MEMBERS(MultiArrayBase);
|
|
|
|
MultiArrayBase(const std::shared_ptr<SRanges>&... ranges);
|
2018-07-21 18:05:53 +02:00
|
|
|
MultiArrayBase(const typename CRange::Space& space);
|
2018-02-16 18:17:22 +01:00
|
|
|
|
|
|
|
virtual ~MultiArrayBase() = default;
|
|
|
|
|
|
|
|
virtual const T& operator[](const IndexType& i) const = 0;
|
|
|
|
virtual const T& at(const typename CRange::IndexType::MetaType& meta) const = 0;
|
|
|
|
|
|
|
|
virtual const T* data() const = 0;
|
|
|
|
|
|
|
|
virtual size_t size() const;
|
|
|
|
virtual bool isSlice() const = 0;
|
|
|
|
|
|
|
|
virtual IndexType begin() const;
|
|
|
|
virtual IndexType end() const;
|
|
|
|
|
|
|
|
virtual IndexType beginIndex() const;
|
|
|
|
virtual IndexType endIndex() const;
|
|
|
|
|
|
|
|
virtual const std::shared_ptr<CRange>& range() const;
|
|
|
|
|
|
|
|
virtual bool isConst() const;
|
|
|
|
|
2018-08-06 15:20:06 +02:00
|
|
|
virtual std::shared_ptr<MultiArrayBase<T,AnonymousRange> > anonymous(bool slice = false) const = 0;
|
2018-07-16 18:52:02 +02:00
|
|
|
|
2018-02-16 18:17:22 +01:00
|
|
|
virtual ConstOperationRoot<T,SRanges...>
|
2018-07-21 18:05:53 +02:00
|
|
|
operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const;
|
2018-08-07 21:49:21 +02:00
|
|
|
|
|
|
|
template <class... MappedRanges>
|
|
|
|
ConstOperationRoot<T,SRanges...>
|
|
|
|
operator()(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const;
|
|
|
|
|
2018-02-16 18:17:22 +01:00
|
|
|
virtual bool isInit() const;
|
2018-05-20 20:03:44 +02:00
|
|
|
|
|
|
|
template <size_t N>
|
|
|
|
auto getRangePtr() const
|
|
|
|
-> decltype(mRange->template getPtr<N>());
|
2018-02-16 18:17:22 +01:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
class MutableMultiArrayBase : public MultiArrayBase<T,SRanges...>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef ContainerRange<T,SRanges...> CRange;
|
|
|
|
typedef MultiArrayBase<T,SRanges...> MAB;
|
2018-03-01 18:16:12 +01:00
|
|
|
typedef ContainerIndex<T,typename SRanges::IndexType...> IndexType;
|
2018-02-16 18:17:22 +01:00
|
|
|
|
|
|
|
using MultiArrayBase<T,SRanges...>::operator[];
|
|
|
|
using MultiArrayBase<T,SRanges...>::at;
|
|
|
|
using MultiArrayBase<T,SRanges...>::data;
|
|
|
|
using MultiArrayBase<T,SRanges...>::begin;
|
|
|
|
using MultiArrayBase<T,SRanges...>::end;
|
|
|
|
|
|
|
|
DEFAULT_MEMBERS(MutableMultiArrayBase);
|
|
|
|
MutableMultiArrayBase(const std::shared_ptr<SRanges>&... ranges);
|
2018-07-21 18:05:53 +02:00
|
|
|
MutableMultiArrayBase(const typename CRange::Space& space);
|
2018-02-16 18:17:22 +01:00
|
|
|
|
|
|
|
virtual T& operator[](const IndexType& i) = 0;
|
|
|
|
virtual T& at(const typename CRange::IndexType::MetaType& meta) = 0;
|
|
|
|
|
|
|
|
virtual T* data() = 0;
|
|
|
|
|
|
|
|
//virtual IndexType begin();
|
|
|
|
//virtual IndexType end();
|
|
|
|
|
|
|
|
virtual bool isConst() const override;
|
|
|
|
|
2018-07-16 18:52:02 +02:00
|
|
|
virtual std::shared_ptr<MultiArrayBase<T,AnonymousRange> > anonymousMove() = 0;
|
|
|
|
|
2018-02-16 18:17:22 +01:00
|
|
|
virtual ConstOperationRoot<T,SRanges...>
|
2018-07-21 18:05:53 +02:00
|
|
|
operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const override;
|
2018-08-07 21:49:21 +02:00
|
|
|
|
2018-07-21 18:05:53 +02:00
|
|
|
virtual OperationRoot<T,SRanges...> operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds);
|
2018-08-07 21:49:21 +02:00
|
|
|
|
|
|
|
template <class... MappedRanges>
|
|
|
|
ConstOperationRoot<T,SRanges...>
|
|
|
|
operator()(const std::shared_ptr<typename MappedRanges::IndexType>&... inds);
|
|
|
|
|
2018-02-16 18:17:22 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
} // end namespace MultiArrayTools
|
|
|
|
|
|
|
|
/* ========================= *
|
|
|
|
* --- TEMPLATE CODE --- *
|
|
|
|
* ========================= */
|
|
|
|
|
|
|
|
namespace MultiArrayTools
|
|
|
|
{
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
* MultiArrayBase *
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
MultiArrayBase<T,SRanges...>::MultiArrayBase(const std::shared_ptr<SRanges>&... ranges)
|
|
|
|
{
|
|
|
|
ContainerRangeFactory<T,SRanges...> crf(ranges...);
|
|
|
|
mRange = std::dynamic_pointer_cast<ContainerRange<T,SRanges...> >( crf.create() );
|
2018-03-05 00:04:50 +01:00
|
|
|
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
|
2018-02-16 18:17:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
2018-07-21 18:05:53 +02:00
|
|
|
MultiArrayBase<T,SRanges...>::MultiArrayBase(const typename CRange::Space& space)
|
2018-02-16 18:17:22 +01:00
|
|
|
{
|
|
|
|
ContainerRangeFactory<T,SRanges...> crf(space);
|
|
|
|
mRange = std::dynamic_pointer_cast<ContainerRange<T,SRanges...> >( crf.create() );
|
2018-03-05 00:04:50 +01:00
|
|
|
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
|
2018-02-16 18:17:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
size_t MultiArrayBase<T,SRanges...>::size() const
|
|
|
|
{
|
|
|
|
return mRange->size();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
typename MultiArrayBase<T,SRanges...>::IndexType MultiArrayBase<T,SRanges...>::begin() const
|
|
|
|
{
|
2018-03-02 13:35:50 +01:00
|
|
|
IndexType i(*mProtoI);
|
|
|
|
i = 0;
|
2018-02-16 18:17:22 +01:00
|
|
|
return i.setData(data());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
typename MultiArrayBase<T,SRanges...>::IndexType MultiArrayBase<T,SRanges...>::end() const
|
|
|
|
{
|
2018-03-02 13:35:50 +01:00
|
|
|
IndexType i(*mProtoI);
|
|
|
|
i = i.max();
|
|
|
|
//i = mRange->size();
|
2018-02-16 18:17:22 +01:00
|
|
|
return i.setData(data());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
typename MultiArrayBase<T,SRanges...>::IndexType
|
|
|
|
MultiArrayBase<T,SRanges...>::beginIndex() const
|
|
|
|
{
|
2018-03-02 13:35:50 +01:00
|
|
|
IndexType i(*mProtoI);
|
|
|
|
i = 0;
|
2018-02-16 18:17:22 +01:00
|
|
|
return i.setData(data());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
typename MultiArrayBase<T,SRanges...>::IndexType
|
|
|
|
MultiArrayBase<T,SRanges...>::endIndex() const
|
|
|
|
{
|
2018-03-02 13:35:50 +01:00
|
|
|
IndexType i(*mProtoI);
|
|
|
|
i = i.max();
|
|
|
|
//i = mRange->size();
|
2018-02-16 18:17:22 +01:00
|
|
|
return i.setData(data());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
const std::shared_ptr<typename MultiArrayBase<T,SRanges...>::CRange>&
|
|
|
|
MultiArrayBase<T,SRanges...>::range() const
|
|
|
|
{
|
|
|
|
return mRange;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
bool MultiArrayBase<T,SRanges...>::isConst() const
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
ConstOperationRoot<T,SRanges...>
|
2018-07-21 18:05:53 +02:00
|
|
|
MultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
2018-02-16 18:17:22 +01:00
|
|
|
{
|
|
|
|
return ConstOperationRoot<T,SRanges...>(*this, inds...);
|
|
|
|
}
|
2018-08-07 21:49:21 +02:00
|
|
|
|
2018-08-07 23:15:31 +02:00
|
|
|
template <typename T, class... SRanges>
|
2018-08-07 21:49:21 +02:00
|
|
|
template <class... MappedRanges>
|
|
|
|
ConstOperationRoot<T,SRanges...>
|
|
|
|
MultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const
|
|
|
|
{
|
|
|
|
static_assert(sizeof...(SRanges) == sizeof...(MappedRanges),
|
|
|
|
"number of mapped ranges must be equal to number of original ranges");
|
2018-08-18 16:40:20 +02:00
|
|
|
return (*this)(MapResult(inds)...); // NO !!!!!
|
2018-08-07 21:49:21 +02:00
|
|
|
}
|
2018-02-16 18:17:22 +01:00
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
bool MultiArrayBase<T,SRanges...>::isInit() const
|
|
|
|
{
|
|
|
|
return mInit;
|
|
|
|
}
|
|
|
|
|
2018-05-20 20:03:44 +02:00
|
|
|
template <typename T, class... SRanges>
|
|
|
|
template <size_t N>
|
|
|
|
auto MultiArrayBase<T,SRanges...>::getRangePtr() const
|
|
|
|
-> decltype(mRange->template getPtr<N>())
|
|
|
|
{
|
|
|
|
return mRange->template getPtr<N>();
|
|
|
|
}
|
|
|
|
|
2018-02-16 18:17:22 +01:00
|
|
|
|
|
|
|
/******************************
|
|
|
|
* MutableMultiArrayBase *
|
|
|
|
******************************/
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
MutableMultiArrayBase<T,SRanges...>::MutableMultiArrayBase(const std::shared_ptr<SRanges>&... ranges) :
|
|
|
|
MultiArrayBase<T,SRanges...>(ranges...) {}
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
2018-07-21 18:05:53 +02:00
|
|
|
MutableMultiArrayBase<T,SRanges...>::MutableMultiArrayBase(const typename CRange::Space& space) :
|
2018-02-16 18:17:22 +01:00
|
|
|
MultiArrayBase<T,SRanges...>(space) {}
|
|
|
|
/*
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
typename MutableMultiArrayBase<T,SRanges...>::IndexType MutableMultiArrayBase<T,SRanges...>::begin()
|
|
|
|
{
|
|
|
|
auto i = mRange->begin();
|
|
|
|
return i.setData(data());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
typename MutableMultiArrayBase<T,SRanges...>::IndexType MutableMultiArrayBase<T,SRanges...>::end()
|
|
|
|
{
|
|
|
|
auto i = mRange->end();
|
|
|
|
return i.setData(data());
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
bool MutableMultiArrayBase<T,SRanges...>::isConst() const
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
OperationRoot<T,SRanges...>
|
2018-07-21 18:05:53 +02:00
|
|
|
MutableMultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds)
|
2018-02-16 18:17:22 +01:00
|
|
|
{
|
|
|
|
return OperationRoot<T,SRanges...>(*this, inds...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... SRanges>
|
|
|
|
ConstOperationRoot<T,SRanges...>
|
2018-07-21 18:05:53 +02:00
|
|
|
MutableMultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
2018-02-16 18:17:22 +01:00
|
|
|
{
|
|
|
|
return ConstOperationRoot<T,SRanges...>(*this, inds...);
|
|
|
|
}
|
|
|
|
|
2018-08-07 23:15:31 +02:00
|
|
|
template <typename T, class... SRanges>
|
2018-08-07 21:49:21 +02:00
|
|
|
template <class... MappedRanges>
|
|
|
|
ConstOperationRoot<T,SRanges...>
|
2018-08-07 23:15:31 +02:00
|
|
|
MutableMultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename MappedRanges::IndexType>&... inds)
|
2018-08-07 21:49:21 +02:00
|
|
|
{
|
|
|
|
static_assert(sizeof...(SRanges) == sizeof...(MappedRanges),
|
|
|
|
"number of mapped ranges must be equal to number of original ranges");
|
|
|
|
return (*this)(MapResult(inds)...);
|
|
|
|
}
|
|
|
|
|
2018-02-16 18:17:22 +01:00
|
|
|
} // end namespace MultiArrayTools
|
|
|
|
|
|
|
|
#endif
|