OpCont: again owns data (can have static size now); use (C)OpRoot for assignment-like operations

This commit is contained in:
Christian Zimmermann 2022-11-27 03:38:10 +01:00
parent 204b726acf
commit 059093241b
6 changed files with 97 additions and 20 deletions

View file

@ -216,6 +216,13 @@ namespace CNORXZ
template <typename T> template <typename T>
using Vector = std::vector<T,Allocator<T>>; using Vector = std::vector<T,Allocator<T>>;
template <typename T, SizeT N, bool Static>
struct Container
{ typedef Vector<T> type; };
template <typename T, SizeT N>
struct Container<T,N,true>
{ typedef Arr<T,N> type; };
} }
#endif #endif

View file

@ -18,7 +18,7 @@ namespace CNORXZ
template <class F, class IndexT> template <class F, class IndexT>
constexpr decltype(auto) COpInterface<OpT>::c(F&& f, const Sptr<IndexT>& ind) const constexpr decltype(auto) COpInterface<OpT>::c(F&& f, const Sptr<IndexT>& ind) const
{ {
return mkContraction(std::forward<F>(f), THIS(), ind); return mkContraction(std::forward<F>(f), THIS().r(), ind);
} }
template <class OpT> template <class OpT>
@ -33,7 +33,7 @@ namespace CNORXZ
template <class F, class... Args> template <class F, class... Args>
constexpr decltype(auto) COpInterface<OpT>::o(F&& f, Args&&... args) const constexpr decltype(auto) COpInterface<OpT>::o(F&& f, Args&&... args) const
{ {
return Operation<F,OpT,Args...>(std::forward<F>(f), THIS(), args...); return mkOperation(std::forward<F>(f), THIS().r(), args...);
} }
@ -45,7 +45,7 @@ namespace CNORXZ
template <class IndexT, class F, class... Args> template <class IndexT, class F, class... Args>
constexpr decltype(auto) OpInterface<OpT>::ax(const Sptr<IndexT>& ind, F&& f, const Args&... args) constexpr decltype(auto) OpInterface<OpT>::ax(const Sptr<IndexT>& ind, F&& f, const Args&... args)
{ {
return ind->ifor( Operation<F,OpT,Args...>(f, THIS(), args...), NoF {} ); return ind->ifor( mkOperation(f, OI::THIS().r(), args...), NoF {} );
} }
template <class OpT> template <class OpT>
@ -126,11 +126,8 @@ namespace CNORXZ
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::init(const Sptr<IndexT>& ind) constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::init(const Sptr<IndexT>& ind)
{ {
mIndex = ind; mIndex = ind;
if(not mC){ if(mC.size() != mIndex->pmax().val()){
mC = std::make_shared<Vector<T>>(mIndex->pmax().val()); mC.resize(mIndex->pmax().val());
}
else if(mC->size() != mIndex->pmax().val()){
mC->resize(mIndex->pmax().val());
} }
return *this; return *this;
} }
@ -140,12 +137,24 @@ namespace CNORXZ
const Vector<T>& c) const Vector<T>& c)
{ {
init(ind); init(ind);
CXZ_ASSERT(c.size() == mC->size(), CXZ_ASSERT(c.size() == mC.size(),
"size-mismatch: expected " << mC->size() << ", got " << c.size()); "size-mismatch: expected " << mC.size() << ", got " << c.size());
std::transform(c.begin(), c.end(), mC->begin(), [](const auto& x) { return x; } ); std::transform(c.begin(), c.end(), mC.begin(), [](const auto& x) { return x; } );
return *this; return *this;
} }
template <typename T, class IndexT>
constexpr decltype(auto) OpCont<T,IndexT>::r()
{
return OpRoot<T,IndexT>(data(), mIndex);
}
template <typename T, class IndexT>
constexpr decltype(auto) OpCont<T,IndexT>::r() const
{
return COpRoot<T,IndexT>(data(), mIndex);
}
template <typename T, class IndexT> template <typename T, class IndexT>
template <class Op> template <class Op>
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::operator=(const Op& o) constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::operator=(const Op& o)
@ -175,23 +184,23 @@ namespace CNORXZ
{ {
if constexpr(is_epos_type<PosT>::value){ if constexpr(is_epos_type<PosT>::value){
if constexpr(pos_type_is_consecutive<PosT>::value){ if constexpr(pos_type_is_consecutive<PosT>::value){
return vreg(mC->data(),pos); return vreg(mC.data(),pos);
} }
else { else {
// non-consecutive data cannot be directly accessed // non-consecutive data cannot be directly accessed
// so there is no non-const (write) access! // so there is no non-const (write) access!
return vreg(const_cast<const T*>(mC->data()),pos); return vreg(const_cast<const T*>(mC.data()),pos);
} }
} }
else { else {
return (*mC)[pos.val()]; return mC[pos.val()];
} }
} }
template <typename T, class IndexT> template <typename T, class IndexT>
constexpr decltype(auto) OpCont<T,IndexT>::operator()() const constexpr decltype(auto) OpCont<T,IndexT>::operator()() const
{ {
return (*mC)[0]; return mC[0];
} }
template <typename T, class IndexT> template <typename T, class IndexT>
@ -204,13 +213,13 @@ namespace CNORXZ
template <typename T, class IndexT> template <typename T, class IndexT>
T* OpCont<T,IndexT>::data() T* OpCont<T,IndexT>::data()
{ {
return mC->data(); return mC.data();
} }
template <typename T, class IndexT> template <typename T, class IndexT>
const T* OpCont<T,IndexT>::data() const const T* OpCont<T,IndexT>::data() const
{ {
return mC->data(); return mC.data();
} }
/**************** /****************
@ -343,6 +352,12 @@ namespace CNORXZ
return ( std::get<Is>(mOps).rootSteps(id) << ... ); return ( std::get<Is>(mOps).rootSteps(id) << ... );
} }
template <class F, class... Ops>
constexpr decltype(auto) mkOperation(F&& f, const Ops&... ops)
{
return Operation<F,Ops...>(std::forward<F>(f), ops...);
}
/********************* /*********************
* Contraction * * Contraction *

View file

@ -20,6 +20,9 @@ namespace CNORXZ
OpT& THIS() { return static_cast<OpT&>(*this); } OpT& THIS() { return static_cast<OpT&>(*this); }
const OpT& THIS() const { return static_cast<const OpT&>(*this); } const OpT& THIS() const { return static_cast<const OpT&>(*this); }
constexpr decltype(auto) r() { return THIS(); }
constexpr decltype(auto) r() const { return THIS(); }
template <class F, class IndexT> template <class F, class IndexT>
constexpr decltype(auto) c(F&& f, const Sptr<IndexT>& ind) const; constexpr decltype(auto) c(F&& f, const Sptr<IndexT>& ind) const;
@ -93,6 +96,8 @@ namespace CNORXZ
{ {
public: public:
typedef OpInterface<OpCont<T,IndexT>> OI; typedef OpInterface<OpCont<T,IndexT>> OI;
typedef typename Container<T,index_const_size<IndexT>::value,
index_has_const_size<IndexT>::value>::type CT;
constexpr OpCont() = default; constexpr OpCont() = default;
@ -100,6 +105,9 @@ namespace CNORXZ
constexpr OpCont& init(const Sptr<IndexT>& ind); constexpr OpCont& init(const Sptr<IndexT>& ind);
constexpr OpCont& init(const Sptr<IndexT>& ind, const Vector<T>& c); constexpr OpCont& init(const Sptr<IndexT>& ind, const Vector<T>& c);
constexpr decltype(auto) r();
constexpr decltype(auto) r() const;
template <class Op> template <class Op>
constexpr OpCont& operator=(const Op& in); constexpr OpCont& operator=(const Op& in);
@ -121,7 +129,7 @@ namespace CNORXZ
private: private:
Sptr<IndexT> mIndex; Sptr<IndexT> mIndex;
Sptr<Vector<T>> mC; CT mC;
}; };
@ -193,6 +201,9 @@ namespace CNORXZ
}; };
template <class F, class... Ops>
constexpr decltype(auto) mkOperation(F&& f, const Ops&... ops);
template <class F, class... Ops> template <class F, class... Ops>
struct op_size<Operation<F,Ops...>> struct op_size<Operation<F,Ops...>>
{ static constexpr SizeT value = sizeof...(Ops); }; { static constexpr SizeT value = sizeof...(Ops); };

View file

@ -74,6 +74,14 @@ namespace CNORXZ
PtrId mPtrId = 0; PtrId mPtrId = 0;
}; };
template <class I>
struct index_has_const_size
{ static constexpr bool value = false; };
template <class I>
struct index_const_size
{ static constexpr SizeT value = 0; };
template <class I, typename MetaType> template <class I, typename MetaType>
IndexPtr<I,MetaType>& operator++(const IndexPtr<I,MetaType>& i); IndexPtr<I,MetaType>& operator++(const IndexPtr<I,MetaType>& i);

View file

@ -110,6 +110,13 @@ namespace CNORXZ
//template <class... Indices> //template <class... Indices>
//using MIndex = GMIndex<None,Indices...>; //using MIndex = GMIndex<None,Indices...>;
template <class... Indices>
struct index_has_const_size<MIndex<Indices...>>
{ static constexpr bool value = (index_has_const_size<Indices>::value and ...); };
template <class... Indices>
struct index_const_size<MIndex<Indices...>>
{ static constexpr SizeT value = (index_const_size<Indices>::value * ...); };
template <class... Ranges> template <class... Ranges>
class MRangeFactory : public RangeFactoryBase class MRangeFactory : public RangeFactoryBase

View file

@ -43,6 +43,35 @@ namespace
COpRoot<double,CIndex> mOp4; COpRoot<double,CIndex> mOp4;
}; };
class OpCont_CR_CR_Test : public ::testing::Test
{
protected:
OpCont_CR_CR_Test()
{
mSize1 = 7;
mSize2 = 11;
const SizeT off = 20;
mData1 = Numbers::get(off, mSize1);
mData2 = Numbers::get(off+mSize1, mSize2);
mData12 = Numbers::get(off+mSize1+mSize2, mSize1*mSize2);
auto cra = CRangeFactory(mSize1).create();
auto crb = CRangeFactory(mSize2).create();
}
SizeT mSize1;
SizeT mSize2;
Vector<Double> mData1;
Vector<Double> mData2;
Vector<Double> mData12;
Sptr<CIndex> mCI1;
Sptr<CIndex> mCI2;
OpCont<double,CIndex> mOp1;
COpRoot<double,CIndex> mOp2;
OpCont<double,CIndex> mOp3;
COpRoot<double,CIndex> mOp4;
};
TEST_F(OpCont_CR_Test, Basics) TEST_F(OpCont_CR_Test, Basics)
{ {
EXPECT_EQ(mOp2.data(), mData1.data()); EXPECT_EQ(mOp2.data(), mData1.data());