I'm specifically asking for an implementation which emulates the C++ Modules static data system for older compilers, but which disables itself and passes through to C++ Modules on newer compilers.
This feels a bit of an overkill for what I am suggesting - after all it is a single template header file (that does not require precompiling).
I would want to see correct handling of exception throws during shared library init and deinit. And running out of memory.
I do not see how what I have will affect the exception handling in any way, but I will add tests for this too.
Well how I handled it was DAG subgroups, so you could tag parts of the DAG as only being possible when a placeholder static init item said it was initialised. Basically I introduced asynchronicity into the static data init system.
I'll admit now I retrofitted it, and the retrofit wasn't great. But it persuades me a decent static data init and deinit system ought to be async capable from the beginning. This is what I mean by thread ordering support, though of course i/o is another good use case e.g. initialise a static variable from the contents of a file.
What I am suggesting is a very simple system to help for resolving the mentioned in the introduction issues. When a global object receives the control to initialize itself, it could apply whatever conditions and whatever source of input. It looks like the DAG system you are referring have a completely different scope of tasks that it was/is solving. I have feeling that we are talking for two completely different things. I have a very raw version of the GOM here: https://github.com/ggeorgiev/gom. If you would like to keep referencing your DAG system it will be helpful if you provide a little bit more information about it. Do you have it published somewhere?