Indexing or referencing into an array of packed elements


#1

If I have a data structure that is essentially a vector of elements, but since there are only a few element values, I’m packing those elements into a bit array, what’s the way in Rust to enable indexing or referencing a specific element inside the packed array?

In C++ in the past I’ve done that like so:

class Packed {
private:
    //! A vector holding the packed elements.
    std::vector<uint64_t> datastore;
    //! number of elements in array.
    size_type len = 0;

public:

    // Individual element reference.
    class reference {
    private:
        size_type position = 0;
        Packed& p;

    public:
        reference(Packed& _p, size_type pos);

        size_type index() const;

        size_type offset() const;

        // Converts the reference into a value.
        operator element_type() const;

        // Set the value of a packed element
        reference& operator=(uint64_t x);

      // and so on...

    };

    reference operator[](size_type pos) {
        return reference(*this, pos);
    };
};

So the packed array class has a reference class which points to both the packed array, and has a position variable that tracks the precise location (which uint64 word and the offset) of the packed element.

Is this the rust-y thing to do or do I have to go about this a different way?


#2

You can implement https://doc.rust-lang.org/std/ops/trait.Index.html for a type.


#3

Take a look at the result of index():

fn index(&self, index: Idx) -> &Self::Output;

It’s often an useless trait, unfortunately…


#4

Depending on how few “few” is, you might just be able to return rvalue statics for each one, like

if (a & m) != 0 { &true } else { &false }

(Of course, that won’t help with IndexMut.)


#5

As others mentioned, std::ops::Index would be the trait to overload the [] operator, but it requires to return a reference. So you’re probably stuck with something like a get() and get_mut() methods that return a reference value.