C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::big_int

From: Jan Schultke <janschultke_at_[hidden]>
Date: Mon, 6 Apr 2026 19:52:52 +0200
On Mon, 6 Apr 2026 at 19:03, Frederick Virchanza Gotham via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> I just want to see if I understand correctly where you're going with
> the whole "value semantics" and "reference counting" . . . . Does the
> following code do what you're saying?
>
> https://godbolt.org/z/zEP397hWb
>
> And here it is copy-pasted:
>
> #include <cstdint>
> #include <atomic>
> #include <type_traits>
>
> // A sample BigInt library to use under the hood:
> #include "
> https://raw.githubusercontent.com/SamHerts/BigInt/refs/heads/main/bigint.h
> "
>
> typedef BigInt::bigint UnderlyingBigIntType;
>
> namespace std {
> template<bool is_thread_safe = false>
> class big_int {
>
> // The next struct is what gets dynamically allocated
> struct DynamicUnit {
> UnderlyingBigIntType bi;
> [[no_unique_address]] conditional_t<is_thread_safe,
> atomic<uintptr_t>,
> uintptr_t > refcount = 1u;
>
> template<typename T> requires is_arithmetic_v<T>
> DynamicUnit(T const arg) : bi(arg) {}
>
> DynamicUnit(char const *const str) : bi(str) {}
>
> DynamicUnit(UnderlyingBigIntType const &rhs) : bi(rhs) {}
> };
>
> DynamicUnit *p;
>
> public:
> ~big_int(void) noexcept
> {
> if ( nullptr == p ) return;
> if ( --(p->refcount) ) return;
> delete p;
> }
>
> template<typename T> requires is_arithmetic_v<T>
> big_int(T const arg) : p( new DynamicUnit(arg) ) {}
>
> big_int(char const *const str) : p( new DynamicUnit(str) ) {}
>
> big_int(big_int const &rhs)
> {
> p = rhs.p;
> ++(p->refcount);
> }
>
> big_int(big_int &&rhs)
> {
> p = rhs.p;
> rhs.p = nullptr;
> }
>
> big_int &operator+=(big_int const &rhs)
> {
> DynamicUnit *const p2 = new DynamicUnit(p->bi);
> p2->bi += rhs.p->bi;
> if ( 0u == --(p->refcount) ) delete p;
> p = p2;
> return *this;
> }
>
> big_int operator+(big_int const &rhs)
> {
> return big_int(*this) += rhs;
> }
>
> int to_int(void)
> {
> return p->bi.operator int();
> }
> };
> } // close namespace std
>
> int main(void)
> {
> std::big_int var("294720952340952937912094251651640921640126512561");
> var += 72;
> return (var + 1).to_int() ? 0 : -1;
> }


Yeah, that's the idea, except it would store small values directly in the
object instead of allocating.

However, I've had a talk with Boost.Multiprecision implementers and they
don't think it's worth it, so I probably won't propose that design.
Instead, big_int would simply have unique ownership over its dynamic data.

Received on 2026-04-06 17:53:11