So, if you wanted to share everything in a shared_ptr
past element x
you could write something like the following:
int main(){
std::shared_ptr<float[]> _vals = std::make_unique<float[]>(70);
for(uint32_t i = 0; i < 10; ++i)
_vals[i] = i;
//range from 2 - end of _vals
// x = 2 in this case
std::shared_ptr<float[]> _partial(_vals, &_vals[2]);
for(uint32_t i = 0; i < 5; ++i)
std::cout<<_partial[i]<<" ";
std::cout<<std::endl;
return 0;
}
so the output would be:
2 3 4 5 6
So _partial
would point from _vals.get() + 2
to the end of _vals
. However what if I wanted to have it point to for example (2-5), (70-end)
for example, I was wondering if I could assign addresses to _partial
to accomplish this?
So if for example this worked:
int main(){
std::shared_ptr<float[]> _vals = std::make_unique<float[]>(70);
for(uint32_t i = 0; i < 70; ++i)
_vals[i] = i;
//range from 2 - 5, and then range from 70-73
std::shared_ptr<float[]> _partial(_vals, &_vals[2]);
float** begin = &(&_vals[70]);
float** end = &(&_vals[73]);
float** beg_2 = &(&_partial[2]);
for(;begin != end; ++(*begin), ++(*beg_2)){
beg_2 = begin;
}
//so technically _partial[0] would point to _vals[2] but _partial[3] would point to _vals[70]
for(uint32_t i = 0; i < 5; ++i)
std::cout<<_partial[i]<<" ";
std::cout<<std::endl;
return 0;
}
However, if I try to compile this, I get the error:
cannot take the address of an rvalue of type 'float *'
float** begin = &(&_vals[70]);
Is there a way to accomplish what I am trying to do?
A shared_ptr
is the wrong tool for this job. A shared_ptr
owns some object and points to some (potentially different) object. It does not implement enough logic to perform a mapping like 0 -> 0, 1 -> 1, 2 -> 2, 3 -> 70
like you want. (Nor should it implement this logic. It's not a simple task.)
Implement your own class to implement this behavior. This should get you started:
template<typename T>
class subsequence {
public:
struct interval { std::size_t begin, length; };
private:
std::shared_ptr<T[]> storage;
std::vector<interval> pieces;
public:
subsequence(std::shared_ptr<T[]> storage, std::initializer_list<interval> pieces)
: storage(std::move(storage)), pieces(pieces) { }
T &operator[](std::size_t i) {
for(interval const &piece : pieces) {
if(i < piece.length) return storage[piece.begin + i];
else i -= piece.length;
}
}
};
int main() {
std::size_t const size = 80;
std::shared_ptr<float[]> vals = std::make_unique<float[]>(size);
for(uint32_t i = 0; i < size; ++i) _vals[i] = i;
subsequence partial(vals, {{2, 3}, {70, 3}}); // range from 2 - 5, and then range from 70-73
for(uint32_t i = 0; i < 6; ++i) std::cout << partial[i] << " ";
std::cout << "\n";
}