OpCont: again owns data (can have static size now); use (C)OpRoot for assignment-like operations
This commit is contained in:
parent
204b726acf
commit
059093241b
6 changed files with 97 additions and 20 deletions
|
@ -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
|
||||||
|
|
|
@ -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 *
|
||||||
|
|
|
@ -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); };
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
|
|
Loading…
Reference in a new issue