generalize cmeta routine for vector meta data + catch 'no range' case in anonymousRange::sreplace(vec)

This commit is contained in:
Christian Zimmermann 2019-08-29 20:40:39 +02:00
parent ba8655896b
commit ea974ce50b
2 changed files with 46 additions and 17 deletions

View file

@ -223,7 +223,30 @@ namespace MultiArrayTools
static constexpr size_t ISDEFAULT = true; static constexpr size_t ISDEFAULT = true;
static constexpr size_t HASMETACONT = false; static constexpr size_t HASMETACONT = false;
}; };
template <typename U>
struct ToCMeta
{
static inline size_t apply(char* target, const U& elem)
{
*reinterpret_cast<U*>(target) = elem;
return sizeof(U);
}
};
template <typename V>
struct ToCMeta<vector<V>>
{
static inline size_t apply(char* target, const vector<V>& elem)
{
size_t o = 0;
for(auto& e: elem){
o += ToCMeta<V>::apply(target, e);
}
return o;
}
};
template <typename U, SpaceType TYPE, size_t S> template <typename U, SpaceType TYPE, size_t S>
class GenSingleRange : public RangeInterface<GenSingleIndex<U,TYPE,S> > class GenSingleRange : public RangeInterface<GenSingleIndex<U,TYPE,S> >
{ {
@ -600,8 +623,9 @@ namespace MultiArrayTools
template <typename U, SpaceType TYPE, size_t S> template <typename U, SpaceType TYPE, size_t S>
size_t GenSingleRange<U,TYPE,S>::cmeta(char* target, size_t pos) const size_t GenSingleRange<U,TYPE,S>::cmeta(char* target, size_t pos) const
{ {
*reinterpret_cast<U*>(target) = mSpace[pos]; //*reinterpret_cast<U*>(target) = mSpace[pos];
return sizeof(U); //return sizeof(U);
return ToCMeta<U>::apply(target, mSpace[pos]);
} }
template <typename U, SpaceType TYPE, size_t S> template <typename U, SpaceType TYPE, size_t S>

View file

@ -231,21 +231,26 @@ namespace MultiArrayTools
std::shared_ptr<AnonymousRange> AnonymousRange::sreplace(const std::shared_ptr<RangeBase>& in, std::shared_ptr<AnonymousRange> AnonymousRange::sreplace(const std::shared_ptr<RangeBase>& in,
const vector<size_t>& num) const const vector<size_t>& num) const
{ {
size_t cnt = num[0]; if(num.size() != 0){
size_t rep_size = 1; size_t cnt = num[0];
// assert continuous ordering or replaced ranges: size_t rep_size = 1;
for(auto& x: num){ // assert continuous ordering or replaced ranges:
assert(cnt++ == x); for(auto& x: num){
rep_size *= mOrig[x]->size(); assert(cnt++ == x);
rep_size *= mOrig[x]->size();
}
assert(rep_size == in->size());
vector<std::shared_ptr<RangeBase>> norig;
norig.reserve(mOrig.size()-num.size()+1);
norig.insert(norig.end(),mOrig.begin(),mOrig.begin()+num[0]);
norig.push_back(in);
norig.insert(norig.end(),mOrig.begin()+num.back()+1,mOrig.end());
AnonymousRangeFactory arf(norig);
return std::dynamic_pointer_cast<AnonymousRange>(arf.create());
}
else {
return std::dynamic_pointer_cast<AnonymousRange>( std::shared_ptr<RangeBase>(RB::mThis) );
} }
assert(rep_size == in->size());
vector<std::shared_ptr<RangeBase>> norig;
norig.reserve(mOrig.size()-num.size()+1);
norig.insert(norig.end(),mOrig.begin(),mOrig.begin()+num[0]);
norig.push_back(in);
norig.insert(norig.end(),mOrig.begin()+num.back()+1,mOrig.end());
AnonymousRangeFactory arf(norig);
return std::dynamic_pointer_cast<AnonymousRange>(arf.create());
} }
const vector<std::shared_ptr<RangeBase> >& AnonymousRange::orig() const const vector<std::shared_ptr<RangeBase> >& AnonymousRange::orig() const