> Whatever you do, do it it in the realm of std::
Point taken.
The complicating factor, and the reason we didn’t just publish the usermode STL as-is, is that much of std:: assumes that C++ exceptions work. Of course there are odds and ends that *do* work without C++ exceptions, (like std::move, std::unique_ptr or all the traits stuff), and I do want to cherry-pick those unmodified. But std::vector, for example, has no way to report errors. We need some new thing to represent a variable-sized array. Or I suppose, do the work to get C++ exceptions onto the kernel’s C runtime. (Although I’m not wild about that idea.)
There’s also some kernel-specific concerns. For example, usermode is pretty okay with assuming a single default allocator for all things. The usermode CRT gives you a default “operator new” that just goes to malloc. But in kernel there is no single pool that’s the right default for everyone. We experimented a bit here. One option is to make the caller always specify the pool:
new (NonPagedNx) Thing();
but that gets difficult when the caller is buried inside some infrastructure, like std::make_unique. Another approach I’ve looked at is to hardcode the pool into the object’s type:
struct Thing : AllocNonPagedNx { };
That lets you call new without additional arguments. But now it’s inflexible – if you implement a string class, you don’t want it to hardcode paged or nonpaged.
This ends up being foundational stuff, so I want to get it right. There really needs to be one set of types that everyone uses, or else you wind up with a fight over which header implements “member operator new” or “global operator new”.
Anyway, we have some C++ headers internally, and I’m slowly improving them. When I get the time, I’m planning on publishing them in a more reusable fashion. (A few of the headers are already on github, buried in a sample driver.)