I'm implementing a fancy pointer type which wraps a parallel memory controller, for pointer-like reading to and writing from external SDRAM. The usage requirements are somewhat as following:
// High level overview of class definition:
class extern_pointer {
class extern_value; // Used as temporary for *e_ptr = ...; etc.
{...}
};
auto e_ptr = hwstl::extern_pointer<struct_in_external_memory>(...);
// set pointer to point to 0x0010000
// extern_pointer&::operator= (e_ptr::address_type); sets internal ptr value
e_ptr = 0x0010000;
// extern_value&::operator= (e_ptr::char_type);
// note: char_type is the minimum size of addressable set of bits,
// variations for extern_value&::operator= are allowed for wider databusses
*e_ptr = 0x60;
// invokes const extern_pointer&::operator*,
// obtains a copy and implicitly converts to
// struct_in_external_memory
struct_in_external_memory v = *e_ptr;
Now as I've been implementing operator* for extern_pointer, I realized operator-> is also a thing.
For operator*, I could just return a temporary extern_value, which overloads some operators to give the pointer-like feeling.
But for -> that isn't the case, since it would require extern_value to contain all the members and methods which refers to the external memory instead.
Is there anything I can do other than deleting extern_value* operator->()?
Edit:
with the declaration of:
class struct_in_external_memory {
void MyMethod() { /* changes some internal stuff */ }
};
Essentially what I want to be able to do is:
e_ptr->MyMethod()
Normally, MyMethod is a member of struct_in_external_memory, but -> needs to return an 'extern_value*'`
Well, depending on struct_in_external_memory and its complexity, you can still implement it. The last link in the chain of calls to operator-> must be a raw pointer, that is unavoidable, but it doesn't mean it has to be a raw pointer to that actual struct.
class extern_value_holder {
struct_in_external_memory copy;
public:
extern_value_holder(/*...*/) {
// this should initialize copy to reflect the value in external memory
}
struct_in_external_memory* operator->() && { return © }
~extern_value_holder() {
//Write copy back to external memory
}
};
Here the returned pointer is to a copy of the object you want to modify, but cant. The caller modifies it, and it is then synchronized automatically when the extern_value_holder reaches the end of its lifetime at the end of the full expression containing the obj->member.
Which brings us back to what I prefaced this with. It depends on struct_in_external_memory, how cheap it is to copy; on can it even be copied. If you want to support multi-threaded environments then you'll need to add synchronization on top.
Which starts to look like a lot of work for very little benefit. It's just one operator after all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With