add WRange (same as URange but with arbitrary meta data ordering)
This commit is contained in:
parent
9ea47a20a3
commit
e8b6dd9f4d
7 changed files with 786 additions and 5 deletions
|
@ -171,12 +171,20 @@ namespace CNORXZ
|
|||
|
||||
// definition: ranges/urange.h
|
||||
template <typename Meta>
|
||||
class URange; // generic simple range (uni-dimensional)
|
||||
class URange; // generic simple range (uni-dimensional, ordered)
|
||||
|
||||
// definition: ranges/urange.h
|
||||
template <typename Meta>
|
||||
class UIndex;
|
||||
|
||||
// definition: ranges/wrange.h
|
||||
template <typename Meta>
|
||||
class WRange; // generic simple range (uni-dimensional)
|
||||
|
||||
// definition: ranges/wrange.h
|
||||
template <typename Meta>
|
||||
class WIndex;
|
||||
|
||||
// definition: ranges/prange.h
|
||||
template <class Range>
|
||||
class PRange;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "mrange.cc.h"
|
||||
#include "xindex.cc.h"
|
||||
#include "urange.cc.h"
|
||||
#include "wrange.cc.h"
|
||||
#include "srange.cc.h"
|
||||
#include "crange.cc.h"
|
||||
#include "prange.cc.h"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "xindex.h"
|
||||
#include "yrange.h"
|
||||
#include "urange.h"
|
||||
#include "wrange.h"
|
||||
#include "srange.h"
|
||||
#include "crange.h"
|
||||
#include "prange.h"
|
||||
|
|
|
@ -395,9 +395,6 @@ namespace CNORXZ
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T> struct is_vector : std::false_type {};
|
||||
template <typename T, typename A> struct is_vector<std::vector<T,A>> : std::true_type {};
|
||||
|
||||
template <typename U>
|
||||
struct URangeCast<Vector<U>>
|
||||
{
|
||||
|
|
|
@ -165,7 +165,7 @@ namespace CNORXZ
|
|||
i.e. the parameter space can be arbitrary. However, the parameter space
|
||||
is assumed to be ordered, i.e. the i-1-th element is assumed to be smaller
|
||||
(according to std::less) than the i-th element.
|
||||
(In the future, there will be another range type, where random ordering is possible.)
|
||||
If you require arbitrary ordering, use WRange / WIndex instead!
|
||||
@tparam MetaT Meta data type.
|
||||
*/
|
||||
template <typename MetaT>
|
||||
|
@ -244,6 +244,11 @@ namespace CNORXZ
|
|||
{
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
// TODO: move to utils file!!!
|
||||
template <typename T> struct is_vector : std::false_type {};
|
||||
template <typename T, typename A> struct is_vector<std::vector<T,A>> : std::true_type {};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
503
src/include/ranges/wrange.cc.h
Normal file
503
src/include/ranges/wrange.cc.h
Normal file
|
@ -0,0 +1,503 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/ranges/wrange.cc.h
|
||||
@brief WRange, WRangeFactory and WIndex implementations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_wrange_cc_h__
|
||||
#define __cxz_wrange_cc_h__
|
||||
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
|
||||
#include "wrange.h"
|
||||
#include "prange.h"
|
||||
#include "index_mul.h"
|
||||
#include "xpr/for.h"
|
||||
#include "operation/op_types.h"
|
||||
#include "operation/op_types.cc.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/*===============+
|
||||
| WIndex |
|
||||
+===============*/
|
||||
|
||||
template <typename MetaT>
|
||||
WIndex<MetaT>::WIndex(const RangePtr& range, SizeT pos) :
|
||||
IndexInterface<WIndex<MetaT>,MetaT>(pos),
|
||||
mRangePtr(rangeCast<RangeType>(range)),
|
||||
mMetaPtr(mRangePtr->get()),
|
||||
mSpaceToPos(mRangePtr->spaceToPos()),
|
||||
mPosToSpace(mRangePtr->posToSpace())
|
||||
{}
|
||||
|
||||
template <typename MetaT>
|
||||
WIndex<MetaT>& WIndex<MetaT>::operator=(size_t lexpos)
|
||||
{
|
||||
IB::mPos = lexpos;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
WIndex<MetaT>& WIndex<MetaT>::operator++()
|
||||
{
|
||||
++IB::mPos;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
WIndex<MetaT>& WIndex<MetaT>::operator--()
|
||||
{
|
||||
--IB::mPos;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
WIndex<MetaT> WIndex<MetaT>::operator+(Int n) const
|
||||
{
|
||||
return WIndex(mRangePtr, IB::mPos + n);
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
WIndex<MetaT> WIndex<MetaT>::operator-(Int n) const
|
||||
{
|
||||
return WIndex(mRangePtr, IB::mPos - n);
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
SizeT WIndex<MetaT>::operator-(const WIndex& i) const
|
||||
{
|
||||
return lex() - i.lex();
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
WIndex<MetaT>& WIndex<MetaT>::operator+=(Int n)
|
||||
{
|
||||
IB::mPos += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
WIndex<MetaT>& WIndex<MetaT>::operator-=(Int n)
|
||||
{
|
||||
IB::mPos -= n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
SizeT WIndex<MetaT>::lex() const
|
||||
{
|
||||
return IB::mPos;
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
UPos WIndex<MetaT>::pmax() const
|
||||
{
|
||||
return UPos(mRangePtr->size());
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
UPos WIndex<MetaT>::lmax() const
|
||||
{
|
||||
return UPos(mRangePtr->size());
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
IndexId<0> WIndex<MetaT>::id() const
|
||||
{
|
||||
return IndexId<0>(this->ptrId());
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
const MetaT& WIndex<MetaT>::operator*() const
|
||||
{
|
||||
return meta();
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
String WIndex<MetaT>::stringMeta() const
|
||||
{
|
||||
return toString(this->meta());
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
const MetaT& WIndex<MetaT>::meta() const
|
||||
{
|
||||
return mMetaPtr[mPosToSpace[IB::mPos]];
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
WIndex<MetaT>& WIndex<MetaT>::at(const MetaT& metaPos)
|
||||
{
|
||||
(*this) = mRangePtr->getMeta(metaPos);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
decltype(auto) WIndex<MetaT>::xpr(const Sptr<WIndex<MetaT>>& _this) const
|
||||
{
|
||||
CXZ_ERROR("not implemented"); // TODO: Operation root with reordered meta data access!!!
|
||||
return coproot(mMetaPtr,_this);
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
RangePtr WIndex<MetaT>::prange(const WIndex<MetaT>& last) const
|
||||
{
|
||||
CXZ_ASSERT(last >= *this, "got last index position (" << last.lex()
|
||||
<< ") smaller than begin index position (" << lex() << ")");
|
||||
const SizeT beginPos = lex();
|
||||
Vector<SizeT> parts(last.lex()-beginPos+1);
|
||||
for(auto i = *this; i != last+1; ++i){
|
||||
parts[i.lex()-beginPos] = i.lex();
|
||||
}
|
||||
return CNORXZ::prange(mRangePtr, parts);
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
SizeT WIndex<MetaT>::deepFormat() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
SizeT WIndex<MetaT>::deepMax() const
|
||||
{
|
||||
return lmax().val();
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
WIndex<MetaT>& WIndex<MetaT>::reformat(const Vector<SizeT>& f, const Vector<SizeT>& s)
|
||||
{
|
||||
CXZ_ASSERT(f[0]*s[0] == lmax().val(), "got wrong extension: " << f[0]*s[0]
|
||||
<< " vs " << lmax().val());
|
||||
CXZ_ASSERT(CNORXZ::formatIsTrivial(f,s), "format is not trivial: f = " << toString(f)
|
||||
<< ", s = " << toString(s));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
size_t WIndex<MetaT>::dim() const // = 1
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
Sptr<WRange<MetaT>> WIndex<MetaT>::range() const
|
||||
{
|
||||
return mRangePtr;
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
template <SizeT I>
|
||||
decltype(auto) WIndex<MetaT>::stepSize(const IndexId<I>& id) const
|
||||
{
|
||||
if constexpr(I != 0){
|
||||
return SPos<0>();
|
||||
}
|
||||
else {
|
||||
return UPos(id == this->id() ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
template <class Xpr, class F>
|
||||
decltype(auto) WIndex<MetaT>::ifor(const Xpr& xpr, F&& f) const
|
||||
{
|
||||
return For<0,Xpr,F>(this->pmax().val(), this->id(), xpr, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
bool WIndex<MetaT>::formatIsTrivial() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename MetaT, class I1>
|
||||
decltype(auto) operator*(const Sptr<WIndex<MetaT>>& a, const Sptr<I1>& b)
|
||||
{
|
||||
return iptrMul(a, b);
|
||||
}
|
||||
|
||||
/*====================+
|
||||
| WRangeFactory |
|
||||
+====================*/
|
||||
|
||||
template <typename MetaT>
|
||||
WRangeFactory<MetaT>::WRangeFactory(const Vector<MetaT>& space) :
|
||||
mSpace(space) {}
|
||||
|
||||
template <typename MetaT>
|
||||
WRangeFactory<MetaT>::WRangeFactory(Vector<MetaT>&& space) :
|
||||
mSpace(space) {}
|
||||
|
||||
template <typename MetaT>
|
||||
WRangeFactory<MetaT>::WRangeFactory(const Vector<MetaT>& space, const RangePtr& ref) :
|
||||
mSpace(space), mRef(ref) {}
|
||||
|
||||
template <typename MetaT>
|
||||
WRangeFactory<MetaT>::WRangeFactory(Vector<MetaT>&& space, const RangePtr& ref) :
|
||||
mSpace(space), mRef(ref) {}
|
||||
|
||||
template <typename MetaT>
|
||||
void WRangeFactory<MetaT>::make()
|
||||
{
|
||||
const auto& info = typeid(WRange<MetaT>);
|
||||
if(mRef != nullptr) {
|
||||
mProd = this->fromCreated(info, {mRef->id()});
|
||||
}
|
||||
if(mProd == nullptr){
|
||||
RangePtr key = mProd = std::shared_ptr<WRange<MetaT>>
|
||||
( new WRange<MetaT>( std::move(mSpace) ) );
|
||||
if(mRef != nullptr) { key = mRef; }
|
||||
this->addToCreated(info, { key->id() }, mProd);
|
||||
}
|
||||
}
|
||||
|
||||
/*=============+
|
||||
| WRange |
|
||||
+=============*/
|
||||
|
||||
template <typename MetaT>
|
||||
void WRange<MetaT>::setupSpace(const Vector<MetaT>& space)
|
||||
{
|
||||
mSpace = space;
|
||||
const SizeT s = mSpace.size();
|
||||
mSpaceToPos.resize(s);
|
||||
mPosToSpace.resize(s);
|
||||
std::sort(mSpace.begin(), mSpace.end(), std::less<MetaT>());
|
||||
auto itdupl = std::adjacent_find(mSpace.begin(), mSpace.end());
|
||||
CXZ_ASSERT(itdupl == mSpace.end(), "found duplicate: " << *itdupl);
|
||||
for(SizeT lx = 0; lx != s; ++lx){
|
||||
for(SizeT sp = 0; sp != s; ++sp){
|
||||
if(space[lx] == mSpace[sp]){
|
||||
mPosToSpace[lx] = sp;
|
||||
mSpaceToPos[sp] = lx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
WRange<MetaT>::WRange(const Vector<MetaT>& space) :
|
||||
RangeInterface<WRange<MetaT>>()
|
||||
{
|
||||
setupSpace(space);
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
WRange<MetaT>::WRange(Vector<MetaT>&& space) :
|
||||
RangeInterface<WRange<MetaT>>()
|
||||
{
|
||||
setupSpace(space);
|
||||
}
|
||||
|
||||
|
||||
template <typename MetaT>
|
||||
const MetaT& WRange<MetaT>::get(SizeT pos) const
|
||||
{
|
||||
return mSpace[mPosToSpace[pos]];
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
const MetaT* WRange<MetaT>::get() const
|
||||
{
|
||||
return mSpace.data();
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
SizeT WRange<MetaT>::getMeta(const MetaT& meta) const
|
||||
{
|
||||
auto b = mSpace.begin();
|
||||
auto e = mSpace.end();
|
||||
auto i = std::lower_bound(b, e, meta, std::less<MetaT>());
|
||||
if(i == e){
|
||||
return size();
|
||||
}
|
||||
if(*i != meta){
|
||||
return size();
|
||||
}
|
||||
return mSpaceToPos[i - b];
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
SizeT WRange<MetaT>::size() const
|
||||
{
|
||||
return mSpace.size();
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
SizeT WRange<MetaT>::dim() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
String WRange<MetaT>::stringMeta(SizeT pos) const
|
||||
{
|
||||
return toString(this->get(pos));
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
const TypeInfo& WRange<MetaT>::type() const
|
||||
{
|
||||
return typeid(WRange<MetaT>);
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
const TypeInfo& WRange<MetaT>::metaType() const
|
||||
{
|
||||
return typeid(MetaT);
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
RangePtr WRange<MetaT>::extend(const RangePtr& r) const
|
||||
{
|
||||
auto rx = rangeCast<WRange<MetaT>>(r);
|
||||
Vector<MetaT> nspace(mSpace.size()+rx->size());
|
||||
SizeT i = 0;
|
||||
for(; i != mSpace.size(); ++i){
|
||||
nspace[i] = mSpace[mPosToSpace[i]];
|
||||
}
|
||||
for(SizeT j = 0; j != rx->mSpace.size(); ++j, ++i){
|
||||
nspace[i] = rx->mSpace[rx->mPosToSpace[j]];
|
||||
}
|
||||
return WRangeFactory<MetaT>( nspace ).create();
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
Vector<Uuid> WRange<MetaT>::key() const
|
||||
{
|
||||
return Vector<Uuid> { this->id() };
|
||||
}
|
||||
|
||||
/*=================+
|
||||
| Range Casts |
|
||||
+=================*/
|
||||
|
||||
template <typename MetaT>
|
||||
struct WRangeCast
|
||||
{
|
||||
template <typename T>
|
||||
static inline Sptr<WRange<MetaT>> transform(const RangePtr& r)
|
||||
{
|
||||
if(r->type() == typeid(PRange<WRange<T>>)){
|
||||
return transform<T>( std::dynamic_pointer_cast<PRange<WRange<T>>>(r)->derive() );
|
||||
}
|
||||
else if(r->type() == typeid(WRange<T>)){
|
||||
auto rr = std::dynamic_pointer_cast<WRange<T>>(r);
|
||||
Vector<MetaT> v(rr->size());
|
||||
std::transform(rr->begin(), rr->end(), v.begin(),
|
||||
[](const T& x) { return static_cast<MetaT>(x); } );
|
||||
return std::dynamic_pointer_cast<WRange<MetaT>>
|
||||
( WRangeFactory<MetaT>(std::move(v)).create() );
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static inline Sptr<WRange<MetaT>> cast(const RangePtr& r)
|
||||
{
|
||||
static_assert(std::is_fundamental<MetaT>::value, "got non-fundamental type");
|
||||
CXZ_ASSERT(r->dim() == 1, "range cast into WRange<Int>: source range must have dim = 1, got " << r->dim());
|
||||
Sptr<WRange<MetaT>> o = nullptr;
|
||||
// TODO: cast from CRange!!!
|
||||
o = transform<SizeT>(r); if(o) return o;
|
||||
o = transform<Int>(r); if(o) return o;
|
||||
o = transform<LInt>(r); if(o) return o;
|
||||
o = transform<Double>(r); if(o) return o;
|
||||
// else general transform using DType (better than nothing), to be implemented!!!
|
||||
CXZ_ERROR("no range cast available for input range '" << r->type().name() << "'");
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U>
|
||||
struct WRangeCast<Vector<U>>
|
||||
{
|
||||
template <typename T>
|
||||
static inline Sptr<WRange<Vector<U>>> transform(const RangePtr& r)
|
||||
{
|
||||
if(r->type() == typeid(WRange<T>)){
|
||||
auto rr = std::dynamic_pointer_cast<WRange<T>>(r);
|
||||
Vector<Vector<U>> v(rr->size());
|
||||
std::transform(rr->begin(), rr->end(), v.begin(),
|
||||
[](const T& x) { return Vector<U> { static_cast<U>(x) }; } );
|
||||
return std::dynamic_pointer_cast<WRange<Vector<U>>>
|
||||
( WRangeFactory<Vector<U>>(std::move(v)).create() );
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, SizeT N>
|
||||
static inline Sptr<WRange<Vector<U>>> atransform(const RangePtr& r)
|
||||
{
|
||||
if(r->type() == typeid(WRange<Arr<T,N>>)){
|
||||
auto rr = std::dynamic_pointer_cast<WRange<Arr<T,N>>>(r);
|
||||
Vector<Vector<U>> v(rr->size());
|
||||
std::transform(rr->begin(), rr->end(), v.begin(),
|
||||
[](const Arr<T,N>& x) {
|
||||
return iter<0,N>( [&](auto i) { return static_cast<U>(x[i]); },
|
||||
[](const auto&... e) { return Vector<U>{ e... }; });
|
||||
} );
|
||||
return std::dynamic_pointer_cast<WRange<Vector<U>>>
|
||||
( WRangeFactory<Vector<U>>(std::move(v)).create() );
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static inline Sptr<WRange<Vector<U>>> cast(const RangePtr& r)
|
||||
{
|
||||
Sptr<WRange<Vector<U>>> o = nullptr;
|
||||
if constexpr(std::is_fundamental<U>::value){
|
||||
o = transform<SizeT>(r); if(o) return o;
|
||||
o = transform<Int>(r); if(o) return o;
|
||||
o = transform<LInt>(r); if(o) return o;
|
||||
o = transform<Double>(r); if(o) return o;
|
||||
o = atransform<SizeT,2>(r); if(o) return o;
|
||||
o = atransform<Int,2>(r); if(o) return o;
|
||||
o = atransform<LInt,2>(r); if(o) return o;
|
||||
o = atransform<Double,2>(r); if(o) return o;
|
||||
o = atransform<SizeT,3>(r); if(o) return o;
|
||||
o = atransform<Int,3>(r); if(o) return o;
|
||||
o = atransform<LInt,3>(r); if(o) return o;
|
||||
o = atransform<Double,3>(r); if(o) return o;
|
||||
}
|
||||
// else general transform using DType (better than nothing), to be implemented!!!
|
||||
CXZ_ERROR("no range cast available for input range '" << r->type().name() << "'");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MetaT>
|
||||
Sptr<WRange<MetaT>> RangeCast<WRange<MetaT>>::func(const RangePtr& r)
|
||||
{
|
||||
if constexpr(std::is_fundamental<MetaT>::value or is_vector<MetaT>::value){
|
||||
return WRangeCast<MetaT>::cast(r);
|
||||
}
|
||||
else {
|
||||
CXZ_ERROR("no range cast available for input range '" << r->type().name() << "'");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename MetaT>
|
||||
RangePtr wrange(const Vector<MetaT>& space)
|
||||
{
|
||||
return WRangeFactory<MetaT>(space).create();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
266
src/include/ranges/wrange.h
Normal file
266
src/include/ranges/wrange.h
Normal file
|
@ -0,0 +1,266 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/ranges/wrange.h
|
||||
@brief WRange, WRangeFactory and WIndex declaration.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_wrange_h__
|
||||
#define __cxz_wrange_h__
|
||||
|
||||
#include "base/base.h"
|
||||
#include "ranges/index_base.h"
|
||||
#include "ranges/range_base.h"
|
||||
#include "xpr/xpr.h"
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
|
||||
/** ****
|
||||
Specific index for WRange.
|
||||
@tparam MetaT Meta data type.
|
||||
*/
|
||||
template <typename MetaT>
|
||||
class WIndex : public IndexInterface<WIndex<MetaT>,MetaT>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef IndexInterface<WIndex<MetaT>,MetaT> IB;
|
||||
typedef WRange<MetaT> RangeType;
|
||||
typedef MetaT MetaType;
|
||||
|
||||
INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType);
|
||||
DEFAULT_MEMBERS(WIndex); /**< default constructors and assignments */
|
||||
|
||||
/** Construct index from range and position.
|
||||
@param range Range to iterate over.
|
||||
@param pos lexicographic position.
|
||||
*/
|
||||
WIndex(const RangePtr& range, SizeT pos = 0);
|
||||
|
||||
/** @copydoc IndexInterface::operator=(SizeT) */
|
||||
WIndex& operator=(SizeT lexpos);
|
||||
|
||||
/** @copydoc IndexInterface::operator++() */
|
||||
WIndex& operator++();
|
||||
|
||||
/** @copydoc IndexInterface::operator--() */
|
||||
WIndex& operator--();
|
||||
|
||||
/** @copydoc IndexInterface::operator+() */
|
||||
WIndex operator+(Int n) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator-() */
|
||||
WIndex operator-(Int n) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator-(WIndex) */
|
||||
SizeT operator-(const WIndex& i) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator+=() */
|
||||
WIndex& operator+=(Int n);
|
||||
|
||||
/** @copydoc IndexInterface::operator-=() */
|
||||
WIndex& operator-=(Int n);
|
||||
|
||||
/** @copydoc IndexInterface::lex() */
|
||||
SizeT lex() const;
|
||||
|
||||
/** @copydoc IndexInterface::pmax() */
|
||||
UPos pmax() const;
|
||||
|
||||
/** @copydoc IndexInterface::lmax() */
|
||||
UPos lmax() const;
|
||||
|
||||
/** @copydoc IndexInterface::id() */
|
||||
IndexId<0> id() const;
|
||||
|
||||
/** @copydoc IndexInterface::operator*() */
|
||||
const MetaT& operator*() const;
|
||||
|
||||
/** @copydoc IndexInterface::dim() */
|
||||
SizeT dim() const; // = 1
|
||||
|
||||
/** @copydoc IndexInterface::range() */
|
||||
Sptr<RangeType> range() const;
|
||||
|
||||
/** @copydoc IndexInterface::stepSize() */
|
||||
template <SizeT I>
|
||||
decltype(auto) stepSize(const IndexId<I>& id) const;
|
||||
|
||||
/** @copydoc IndexInterface::stringMeta() */
|
||||
String stringMeta() const;
|
||||
|
||||
/** @copydoc IndexInterface::meta() */
|
||||
const MetaT& meta() const;
|
||||
|
||||
/** @copydoc IndexInterface::at() */
|
||||
WIndex& at(const MetaT& metaPos);
|
||||
|
||||
/** @copydoc IndexInterface::prange() */
|
||||
RangePtr prange(const WIndex<MetaType>& last) const;
|
||||
|
||||
/** @copydoc IndexInterface::deepFormat() */
|
||||
SizeT deepFormat() const;
|
||||
|
||||
/** @copydoc IndexInterface::deepMax() */
|
||||
SizeT deepMax() const;
|
||||
|
||||
/** @copydoc IndexInterface::reformat() */
|
||||
WIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
||||
|
||||
/** @copydoc IndexInterface::ifor() */
|
||||
template <class Xpr, class F>
|
||||
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
||||
|
||||
/** @copydoc IndexInterface::formatIsTrivial() */
|
||||
bool formatIsTrivial() const;
|
||||
|
||||
/** @copydoc IndexInterface::xpr() */
|
||||
decltype(auto) xpr(const Sptr<WIndex<MetaType>>& _this) const;
|
||||
|
||||
private:
|
||||
Sptr<RangeType> mRangePtr;
|
||||
const MetaT* mMetaPtr;
|
||||
const SizeT* mSpaceToPos;
|
||||
const SizeT* mPosToSpace;
|
||||
};
|
||||
|
||||
template <typename MetaT>
|
||||
void swap(WIndex<MetaT>& a, WIndex<MetaT>& b) { a.swap(b); }
|
||||
|
||||
/** Make index pack of a WIndex and another index.
|
||||
@param a pointer to WIndex.
|
||||
@param b pointer to another index.
|
||||
*/
|
||||
template <typename MetaT, class I1>
|
||||
decltype(auto) operator*(const Sptr<WIndex<MetaT>>& a, const Sptr<I1>& b);
|
||||
|
||||
/** ****
|
||||
Specific factory for WRange.
|
||||
@tparam MetaT Meta data type.
|
||||
*/
|
||||
template <typename MetaT>
|
||||
class WRangeFactory : public RangeFactoryBase
|
||||
{
|
||||
public:
|
||||
WRangeFactory(const Vector<MetaT>& space);
|
||||
WRangeFactory(Vector<MetaT>&& space);
|
||||
WRangeFactory(const Vector<MetaT>& space, const RangePtr& ref);
|
||||
WRangeFactory(Vector<MetaT>&& space, const RangePtr& ref);
|
||||
|
||||
private:
|
||||
WRangeFactory() = default;
|
||||
virtual void make() override final;
|
||||
|
||||
Vector<MetaT> mSpace;
|
||||
RangePtr mRef;
|
||||
};
|
||||
|
||||
/** ****
|
||||
Uni-(1-)dimensional range with non-trivial meta data space
|
||||
i.e. the parameter space can be arbitrary. In contrast to URange
|
||||
the meta data can have arbitrary ordering.
|
||||
Note: Internally, the meta data is still ordered for the sake of performance during look-up.
|
||||
The externally visible non-ordering is realized through maps between the internal (meta space)
|
||||
ordering, and the externally visible lexicographic ordering.
|
||||
@tparam MetaT Meta data type.
|
||||
*/
|
||||
template <typename MetaT>
|
||||
class WRange : public RangeInterface<WRange<MetaT>>
|
||||
{
|
||||
public:
|
||||
typedef RangeBase RB;
|
||||
typedef WIndex<MetaT> IndexType;
|
||||
typedef MetaT MetaType;
|
||||
|
||||
friend WRangeFactory<MetaType>;
|
||||
|
||||
virtual SizeT size() const override final;
|
||||
virtual SizeT dim() const override final;
|
||||
virtual String stringMeta(SizeT pos) const override final;
|
||||
virtual const TypeInfo& type() const override final;
|
||||
virtual const TypeInfo& metaType() const override final;
|
||||
virtual RangePtr extend(const RangePtr& r) const override final;
|
||||
|
||||
/** Get meta data at given range position.
|
||||
@param pos Integer indicating requested position.
|
||||
@return Meta data at given postion.
|
||||
*/
|
||||
const MetaType& get(SizeT pos) const;
|
||||
|
||||
/** Get range position for given meta data.
|
||||
Returns size() if metaPos is not part of the range.
|
||||
@param metaPos Meta data.
|
||||
@return Position of the given meta data if it is contained by the range.
|
||||
*/
|
||||
SizeT getMeta(const MetaType& metaPos) const;
|
||||
|
||||
/** Get meta data array.
|
||||
@return Pointer to first element (memory ordering) of the underlying meta data array.
|
||||
*/
|
||||
const MetaType* get() const;
|
||||
|
||||
/** Get map from meta space memory position to lexicographic position.
|
||||
@return Pointer to first element of the map.
|
||||
*/
|
||||
const SizeT* spaceToPos() const;
|
||||
|
||||
/** Get map from lexicographic position to meta space memory position.
|
||||
@return Pointer to first element of the map.
|
||||
*/
|
||||
const SizeT* posToSpace() const;
|
||||
|
||||
private:
|
||||
|
||||
void setupSpace(const Vector<MetaT>& space);
|
||||
|
||||
WRange() = default;
|
||||
WRange(const WRange& in) = delete;
|
||||
WRange(const Vector<MetaType>& space);
|
||||
WRange(Vector<MetaType>&& space);
|
||||
|
||||
Vector<MetaType> mSpace;
|
||||
Vector<SizeT> mSpaceToPos;
|
||||
Vector<SizeT> mPosToSpace;
|
||||
|
||||
virtual Vector<Uuid> key() const override final;
|
||||
|
||||
SERIALIZATION_FUNCTIONS_NOPUB;
|
||||
};
|
||||
|
||||
/** ***
|
||||
Specialize RangeCast for casts to WRange
|
||||
@see RangeCast
|
||||
*/
|
||||
template <typename MetaType>
|
||||
struct RangeCast<WRange<MetaType>>
|
||||
{
|
||||
/** cast the range */
|
||||
static Sptr<WRange<MetaType>> func(const RangePtr& r);
|
||||
};
|
||||
|
||||
/** Create an WRange, calls WRangeFactory.
|
||||
@param space Meta data space to create an WRange on.
|
||||
@return Created range.
|
||||
*/
|
||||
template <typename MetaT>
|
||||
RangePtr wrange(const Vector<MetaT>& space);
|
||||
|
||||
/** ***
|
||||
WIndex can be used as expression
|
||||
@see index_expression_exists
|
||||
*/
|
||||
template <typename MetaT>
|
||||
struct index_expression_exists<WIndex<MetaT>>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue