- For consistency, we will want configurable allocators; we have them
everywhere, even though the "common" vocabulary type uses a default
(cf. std::string).
I'm not so sure about that. I would need some library experts to share their thoughts. We don't usually provide allocator support when there is some kind of type erasure going on, or the type of allocator is not obvious. One problem here is that if you reference count, you want a single allocation for the reference counter and for the limb array, so if you're given std::allocator<limb_type>, you need to rebind that.
Anyway, this may be an area of the standard where we deliberately don't support allocators.
- gcc's reference-counted string failed at least on the front of
not being able to satisfy the standard's requirements on simultaneous
use across threads, if I remember correctly. It also took a while
to actually get all the places right where an "unshare" operation
was needed. Since users won't be able to look at the elementary
items composing a big_int, that's probably less of an issue.
I'm also not entirely sure whether we want to provide access to the underlying limb array or not.
- For a reference-counted big_int, we need a multi-threading story:
Do we do atomic reference counting? If so, that's a dead end for some.
If not, creating two copies of a value in two different threads fails,
which is not in harmony with the standard library's expectation of
multi-thread compatibility.
I don't think that copies across threads would be acceptable, and it would be way too bug-prone, so it's either going to be atomic reference counting, or unique ownership. I like the reference counting more right now, but I'll have to see through benchmarks of how much cost that actually incurs.
- Can we get the core algorithms (operating on byte streams or so),
independent of the memory management concerns?
I was drafting up something along those lines at some point, but you can only do so for a handful of operations, such as addition and bit-shifting. Once you do multiplication, division, or many other operations, you need additional allocations to store temporary results, and I don't see much value in standardizing the core algorithms if those are ridden with an unspecified amount of extra allocations. std::big_int would be used in its own implementation, so to speak.