Date: Mon, 6 Apr 2026 18:02:55 +0100
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;
}
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;
}
Received on 2026-04-06 17:03:14
