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

@ -215,7 +215,14 @@ namespace CNORXZ
template <typename 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

View file

@ -18,7 +18,7 @@ namespace CNORXZ
template <class F, class IndexT>
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>
@ -33,7 +33,7 @@ namespace CNORXZ
template <class F, class... Args>
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>
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>
@ -126,11 +126,8 @@ namespace CNORXZ
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::init(const Sptr<IndexT>& ind)
{
mIndex = ind;
if(not mC){
mC = std::make_shared<Vector<T>>(mIndex->pmax().val());
}
else if(mC->size() != mIndex->pmax().val()){
mC->resize(mIndex->pmax().val());
if(mC.size() != mIndex->pmax().val()){
mC.resize(mIndex->pmax().val());
}
return *this;
}
@ -140,12 +137,24 @@ namespace CNORXZ
const Vector<T>& c)
{
init(ind);
CXZ_ASSERT(c.size() == mC->size(),
"size-mismatch: expected " << mC->size() << ", got " << c.size());
std::transform(c.begin(), c.end(), mC->begin(), [](const auto& x) { return x; } );
CXZ_ASSERT(c.size() == mC.size(),
"size-mismatch: expected " << mC.size() << ", got " << c.size());
std::transform(c.begin(), c.end(), mC.begin(), [](const auto& x) { return x; } );
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 <class Op>
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(pos_type_is_consecutive<PosT>::value){
return vreg(mC->data(),pos);
return vreg(mC.data(),pos);
}
else {
// non-consecutive data cannot be directly accessed
// 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 {
return (*mC)[pos.val()];
return mC[pos.val()];
}
}
template <typename T, class IndexT>
constexpr decltype(auto) OpCont<T,IndexT>::operator()() const
{
return (*mC)[0];
return mC[0];
}
template <typename T, class IndexT>
@ -204,13 +213,13 @@ namespace CNORXZ
template <typename T, class IndexT>
T* OpCont<T,IndexT>::data()
{
return mC->data();
return mC.data();
}
template <typename T, class IndexT>
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) << ... );
}
template <class F, class... Ops>
constexpr decltype(auto) mkOperation(F&& f, const Ops&... ops)
{
return Operation<F,Ops...>(std::forward<F>(f), ops...);
}
/*********************
* Contraction *

View file

@ -20,6 +20,9 @@ namespace CNORXZ
OpT& THIS() { return static_cast<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>
constexpr decltype(auto) c(F&& f, const Sptr<IndexT>& ind) const;
@ -93,13 +96,18 @@ namespace CNORXZ
{
public:
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(const Sptr<IndexT>& ind);
constexpr OpCont& init(const Sptr<IndexT>& ind);
constexpr OpCont& init(const Sptr<IndexT>& ind, const Vector<T>& c);
constexpr decltype(auto) r();
constexpr decltype(auto) r() const;
template <class Op>
constexpr OpCont& operator=(const Op& in);
@ -121,7 +129,7 @@ namespace CNORXZ
private:
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>
struct op_size<Operation<F,Ops...>>
{ static constexpr SizeT value = sizeof...(Ops); };

View file

@ -74,6 +74,14 @@ namespace CNORXZ
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>
IndexPtr<I,MetaType>& operator++(const IndexPtr<I,MetaType>& i);

View file

@ -110,6 +110,13 @@ namespace CNORXZ
//template <class... 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>
class MRangeFactory : public RangeFactoryBase

View file

@ -43,6 +43,35 @@ namespace
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)
{
EXPECT_EQ(mOp2.data(), mData1.data());