[comp.lang.c++] "virtual" arrays - how to

roger@procase.UUCP (Roger H. Scott) (07/16/90)

Following is a complete, working example of what I call a "virtual" array.
This posting is in response to a recent question about how to construct
"arrays" of things that are not addressable (i.e., you can't just define
a "T& operator[](int)" because T is something like a bit or a nibble).
Virtual arrays are also useful for emulation of memory-mapped I/O and
emulation of virtual memory - you can have an array that is logically much
larger than it is "physically", and you can tell the difference between
reads and writes to the array (important if you are managing "dirty bits",
for instance).  Enjoy.


#include <stdio.h>
#define ASSERT(e)
typedef int T; // we are creating an array of T
class VirtualArray;

class VirtualArrayReference {
public:
    VirtualArrayReference(VirtualArray *aa, int ii) : a(aa), i(ii) {}
    operator T();
    T operator=(T);

private:
    VirtualArray *a;
    int i;
};

// This example is an array of 256 1-bit integers.

class VirtualArray {
public:
    VirtualArray();
    ~VirtualArray() {}

    T writeAt(int i, T d) {
	ASSERT(0 <= i && i < 8 * 32);
	ASSERT(0 <= d && d <= 1);
	a[i >> 5] |= (1 << (i & 31));
	return d;
    }

    T readAt(int i) {
	ASSERT(0 <= i && i < 8 * 32);
	return a[i >> 5] & (1 << (i & 31));
    }

    VirtualArrayReference operator[](int i) {
	return VirtualArrayReference(this, i);
    }

private:
    unsigned a[8];
};

inline
VirtualArrayReference::operator T() {
    return a->readAt(i);
}

inline
T
VirtualArrayReference::operator=(T d) {
    return a->writeAt(i, d);
}

// ********************************************************

VirtualArray::VirtualArray() {
    int i;
    for (i = 0; i < 8; ++i)
	a[i] = 0;
}

// Test the array by setting the first few prime-numbered entries
// to 1 and then seeing which ones got set.

main() {
    VirtualArray a;

    static int primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23,
	29, 31, 37, 41, 43, 47, 53, 59, 61, 0 };
    
    int i;
    for (i = 0; primes[i] != 0; ++i)
	a[primes[i]] = 1;
    
    for (i = 0; i < 256; ++i)
	if (a[i])
	    printf("%d\n", i);
}