views:

49

answers:

0

My container needs to store a little information about its elements. Normally, I store this separately from elements. However, I'd like to give users possibility to conserve memory by dedicating a field in element structure type for external use. E.g.:

struct MyStuff
{
  int           foo;
  char          bar;
  mutable char  dedicated_for_external_use;  // Because of alignment, this field
                                             // won't increase sizeof (MyStuff)
};

The idea here is that the field must not be accessed by anything but element's container. Since containers store a copy (much like std::vector), it wouldn't be a problem if you added any given value x to several containers.

How would you design an interface for this that, if possible, would meet the following requirements?

  • Should be completely optional. I.e. it should be possible to automatically determine if given type provides such a field or not and then container would only use it if available.
  • Ideally, wouldn't depend on type traits etc. as I need maximum compiler compatibility.
  • Should be easy to use. I.e. if you can and want to enable this optimization for type MyStuff, you could do it with 3 lines of code, not 25. Internal complications, on the other hand, don't matter.
  • Should preferably exclude false positives completely. What I mean is: if you check for field foo_bar there is a small posibility that such field exists for a completely unrelated reason (and I think duck-typing is simply not for C++). A better way would be to check if type inherits marker class ProvidesExternalUseField from my library, as this can't be by accident.

EDIT

I know about Boost.Intrusive, but what I want is something different. If I go that way and create a hooks class with a single char field, it cannot be used to conserve memory in many cases. If inherited type has an int as first field, char field will be padded to 4 bytes. I.e. you'd often need intricate knowledge of type internals to be able to "squeeze" such extern-use field in, but inheritance doesn't really provide it:

struct hooks { mutable char dedicated_for_external_use; };
struct MyStuff : hooks
{
  int           foo;
  char          bar;
};

Here, size of MyStuff will be 12 bytes, not 8.