Make ESM::RefId to be fixed size cheap to copy and support different implementation types
Use std::variant to store monostate representing empty RefId, FormId or a pointer to string RefId. ESM::RefId should fit into 2 CPU registers (16 bytes on x86-64). Store refId strings in std::unordered_set and use pointer to an item there. Inserts to std::unordered_set do not invalidate pointers to values so the pointer is always valid. Elements are not removed. Assume there is finite number of string refIds. The set is protected by a mutex because access may happen from multiple threads. This is not ideal but I don't think it's possible to scope this to 1 thread. But it should be possible to replace it with concurrent map implementation which means a new dependency.
To make sure there is a finite number of refIds, use std::uint64_t for generated ones instead of strings. Support writing and reading typed RefIds from ESM files. Increment save game number and make sure ESM reader reads old format files as before.
Alternative to !2704 (closed) which goes into a direction opposite of the original idea for this type. I could just add comments there but I think it's more efficient just to create another MR.
There is still some work to do. Reading of a new typed RefId is not done everywhere but I want to show basic idea first.