add null range + static function base class

This commit is contained in:
Christian Zimmermann 2018-07-17 20:01:25 +02:00
parent a5292ef2ab
commit 4499dfd7fc
7 changed files with 294 additions and 2 deletions

View file

@ -2,9 +2,63 @@
#ifndef __arith_h__
#define __arith_h__
namespace MultiArrayHelper
namespace MultiArrayTools
{
template <size_t N>
struct ArgPack
{
template <class F, class Tuple, typename... As>
static inline auto mk(const Tuple& tp, As... as)
-> decltype(ArgPack<N-1>::mk(tp, std::get<N>(tp), as...))
{
return ArgPack<N-1>::mk(tp, std::get<N>(tp), as...);
}
};
template <>
struct ArgPack<0>
{
template <class F, class Tuple, typename... As>
static inline auto mk(const Tuple& tp, As... as)
-> decltype(F::apply(std::get<0>(tp), as...))
{
return F::apply(std::get<0>(tp), as...);
}
};
template <typename T, class F, typename... As>
struct StaticFunctionBase
{
static constexpr bool FISSTATIC = true;
typedef T value_type;
template <class... Ops>
static auto mk(const Ops&... ops)
-> Operation<T,F,Ops...>
{
return Operation<T,F,Ops...>(ops...);
}
static inline T apply(const std::tuple<As...>& arg)
{
return ArgPack<sizeof...(As)-1>::template mk<F,std::tuple<As...> >(arg);
}
};
// OPERATIONS (STATIC)
template <typename T>
struct identity : public StaticFunctionBase<T, identity<T>, T>
{
//static constexpr bool FISSTATIC = true;
using StaticFunctionBase<T, identity<T>, T>::apply;
static inline T apply(T a)
{
return a;
}
};
template <typename T>
struct plus
{

View file

@ -40,6 +40,10 @@ namespace MultiArrayTools
template <typename T, class... Ranges>
class OperationRoot;
// multi_array_operation.h
template <typename T>
class OperationValue;
// multi_array_operation.h
template <typename T, class... Ranges>
class ConstOperationRoot;

View file

@ -39,6 +39,7 @@ namespace MultiArrayTools
MultiArray(const std::shared_ptr<SRanges>&... ranges, std::vector<T>&& vec);
MultiArray(const typename CRange::SpaceType& space);
MultiArray(const typename CRange::SpaceType& space, std::vector<T>&& vec);
MultiArray(MultiArray<T,AnonymousRange>& ama, SIZET<SRanges>... sizes);
// Only if ALL ranges have default extensions:
//MultiArray(const std::vector<T>& vec);
@ -86,7 +87,10 @@ namespace MultiArrayTools
};
template <typename T>
using Scalar = MultiArray<T>;
using Scalar = MultiArray<T,NullRange>;
template <typename T>
Scalar<T> scalar(const T& in);
template <typename T, class... ERanges>
struct ArrayCatter<MultiArray<T,ERanges...> >
@ -119,6 +123,12 @@ namespace MultiArrayTools
namespace MultiArrayTools
{
template <typename T>
Scalar<T> scalar(const T& in)
{
NullRF nrf;
return Scalar<T>( std::dynamic_pointer_cast<NullRange>( nrf.create() ), std::vector<T>( { in } ) );
}
/*******************
* MultiArray *
@ -175,6 +185,14 @@ namespace MultiArrayTools
}
}
template <typename T, class... SRanges>
MultiArray<T,SRanges...>::MultiArray(MultiArray<T,AnonymousRange>& ama, SIZET<SRanges>... sizes) :
MutableMultiArrayBase<T,SRanges...>( ama.range()->template scast<SRanges...>(sizes...)->space() ),
mCont( std::move( ama.mCont ) )
{
MAB::mInit = true;
}
/*
template <typename T, class... SRanges>
template <class Range2, class Range3>

View file

@ -33,6 +33,11 @@ namespace MultiArrayTools
OperationClass& THIS() { return static_cast<OperationClass&>(*this); }
const OperationClass& THIS() const { return static_cast<OperationClass const&>(*this); }
//inline auto operator+(const T& in) const
// -> Operation<T,plus<T>,OperationClass,OperationValue<T> >;
// !!!
template <class Second>
auto operator+(const Second& in) const
-> Operation<T,plus<T>,OperationClass,Second>;
@ -196,6 +201,30 @@ namespace MultiArrayTools
IndexType mIndex;
};
template <typename T>
class OperationValue : public OperationTemplate<T,OperationValue<T> >
{
typedef T value_type;
typedef OperationBase<T,OperationValue<T> > OT;
typedef ContainerRange<T,NullRange> CRange;
typedef ContainerIndex<T,NullIndex> IndexType;
static constexpr size_t SIZE = 1;
OperationValue(const T& val);
template <class ET>
inline T get(ET pos) const;
MExt<void> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
template <class Expr>
Expr loop(Expr exp) const;
private:
T mVal;
};
template <class Op>
size_t sumRootNum()
{
@ -324,6 +353,15 @@ namespace MultiArrayTools
* OperationTemplate *
***************************/
/*
template <typename T, class OperationClass>
auto OperationBase<T,OperationClass>::operator+(const T& in) const
-> Operation<T,plus<T>,OperationClass,OperationValue<T> >
{
return Operation<T,plus<T>,OperationClass,OperationValue<T> >(THIS(), in);
}
*/
template <typename T, class OperationClass>
template <class Second>
auto OperationBase<T,OperationClass>::operator+(const Second& in) const
@ -525,6 +563,31 @@ namespace MultiArrayTools
return mDataPtr + mIndex.pos();
}
template <typename T>
OperationValue<T>::OperationValue(const T& val) : mVal(val) {}
template <typename T>
template <class ET>
inline T OperationValue<T>::get(ET pos) const
{
return mVal;
}
template <typename T>
MExt<void> OperationValue<T>::rootSteps(std::intptr_t iPtrNum) const
{
return MExt<void>(0);
}
template <typename T>
template <class Expr>
Expr OperationValue<T>::loop(Expr exp) const
{
return exp;
}
/*******************
* Operation *
*******************/

View file

@ -14,6 +14,7 @@
//#ifndef __ranges_header__
//#define __ranges_header__
#include "null_range.h"
#include "spin_range.h"
#include "space_range.h"
#include "classic_range.h"

View file

@ -0,0 +1,76 @@
#ifdef include_range_type
include_range_type(NUL,-2)
#else
#ifdef __ranges_header__
// assert, that this is only used within range_types/header.h
//#ifndef __spin_range_h__
//#define __spin_range_h__
namespace MultiArrayTools
{
typedef SingleIndex<size_t,SpaceType::NUL> NullIndex;
template <>
class SingleRangeFactory<size_t,SpaceType::NUL> : public RangeFactoryBase
{
public:
typedef SingleRange<size_t,SpaceType::NUL> oType;
SingleRangeFactory();
std::shared_ptr<RangeBase> create();
};
template <>
class SingleRange<size_t,SpaceType::NUL> : public RangeInterface<NullIndex>
{
public:
typedef RangeBase RB;
typedef typename RangeInterface<SingleIndex<size_t,SpaceType::NUL> >::IndexType IndexType;
typedef SingleRange<size_t,SpaceType::NUL> RangeType;
typedef size_t MetaType;
virtual size_t size() const override;
virtual size_t dim() const override;
size_t get(size_t pos) const;
size_t getMeta(size_t metapos) const;
virtual IndexType begin() const override;
virtual IndexType end() const override;
//virtual std::shared_ptr<VIWB> index() const override;
friend SingleRangeFactory<size_t,SpaceType::NUL>;
static constexpr bool defaultable = true;
static constexpr size_t ISSTATIC = 1;
static constexpr size_t SIZE = 1;
static constexpr bool HASMETACONT = false;
static SingleRangeFactory<size_t,SpaceType::NUL> factory()
{ return SingleRangeFactory<size_t,SpaceType::NUL>(); }
protected:
SingleRange() = default;
SingleRange(const SingleRange& in) = delete;
//SingleRange(size_t spinNum);
};
typedef SingleRange<size_t,SpaceType::NUL> NullRange;
typedef SingleRangeFactory<size_t,SpaceType::NUL> NullRF;
}
//#endif // #ifndef __spin_range_h__
#endif // #ifdef __ranges_header__
#endif // #ifdef include_range_type

View file

@ -0,0 +1,76 @@
#include "ranges/rheader.h"
namespace MultiArrayTools
{
/********************
* SingleRange *
********************/
SingleRangeFactory<size_t,SpaceType::NUL>::SingleRangeFactory()
{
// Quasi Singleton
if(not mProd){
mProd = std::shared_ptr<oType>( new SingleRange<size_t,SpaceType::NUL>() );
setSelf();
}
}
std::shared_ptr<RangeBase> SingleRangeFactory<size_t,SpaceType::NUL>::create()
{
return mProd;
}
/********************
* SingleRange *
********************/
size_t SingleRange<size_t,SpaceType::NUL>::get(size_t pos) const
{
return 0;
}
size_t SingleRange<size_t,SpaceType::NUL>::getMeta(size_t metapos) const
{
return 0;
}
size_t SingleRange<size_t,SpaceType::NUL>::size() const
{
return 1;
}
size_t SingleRange<size_t,SpaceType::NUL>::dim() const
{
return 1;
}
typename SingleRange<size_t,SpaceType::NUL>::IndexType SingleRange<size_t,SpaceType::NUL>::begin() const
{
SingleIndex<size_t,SpaceType::NUL> i( std::dynamic_pointer_cast<SingleRange<size_t,SpaceType::NUL> >
( std::shared_ptr<RangeBase>( RB::mThis ) ) );
i = 0;
return i;
}
typename SingleRange<size_t,SpaceType::NUL>::IndexType SingleRange<size_t,SpaceType::NUL>::end() const
{
SingleIndex<size_t,SpaceType::NUL> i( std::dynamic_pointer_cast<SingleRange<size_t,SpaceType::NUL> >
( std::shared_ptr<RangeBase>( RB::mThis ) ) );
i = size();
return i;
}
// put this in the interface class !!!
/*
std::shared_ptr<VIWB> SingleRange<size_t,SpaceType::NUL>::index() const
{
typedef IndexWrapper<IndexType> IW;
return std::make_shared<IW>
( std::make_shared<IndexType>
( std::dynamic_pointer_cast<SingleRange<size_t,SpaceType::NUL> >
( std::shared_ptr<RangeBase>( RB::mThis ) ) ) );
}
*/
}