Lets say I want to write an intrusive list. I have an intrusive list class template that takes the type and a pointer to the member to use as the node. It looks roughly like this:
// This needs to be a member of anything the intrusive list is going to store.
class IntrusiveListNode {
// ...
}
// The intrusive list itself
template <class T, IntrusiveListNode T::*Member>
class IntrusiveList {
// ...
};
// This is a type that is going to be stored in an intrusive list.
class IntegerListNode {
public:
IntrusiveListNode node;
private:
int value;
};
// An example of the how the list would be used.
IntrusiveList<IntegerListNode, &IntegerListNode::node> myList;
Each thing you want to store in the list has an IntrusiveListNode on it. To turn that IntrusiveListNode back into a thing you can use, like an IntegerListNode, you call a function which does some pointer arithmetic on the node based on it's offset in the class, then casts it to the appropriate type. This seems to work, but I think it's not guaranteed to.
I'd like to be able to add a static_assert to my class that verifies at compile time that the type you're using is safe, but I'm not sure what the static_assert's condition would be. I think this is only guaranteed to work if the type holding the IntrusiveListNode is a standard layout class, but I'm not sure since the requirements for standard layout types seem stricter than I actually need.
In particular, a standard layout type requires that all members have the same access control. What I need is to just be able to make sure pointer arithmetic will work. That would mean you couldn't use this on a polymorphic type because two different versions of the struct could be laid out differently, but this shouldn't be an issue if the type has some mix of private and public data members, right? Would it be safe if I just required that the type be non-polymorphic? Or is there a better check to do? Or am I stuck doing an is_standard_layout
check?