If you only need to do addition
#include<cstdint>
#include<limits>
#include<utility>
using std::uint64_t;
std::pair<uint64_t, int> add_with_carry(uint64_t a, uint64_t b)
{
if(a > std::numeric_limits<uint64_t>::max() - b)
return {a + b, 1};
else
return {a + b, 0};
}
auto [sum, carry] = add_with_carry(a, b);
And to extend to arbitrary chained additions
std::pair<uint64_t, int> add_with_carry(std::pair<uint64_t, int> a)
{
return a;
}
template<typename... Addends>
std::pair<uint64_t, int> add_with_carry(std::pair<uint64_t, int> a, uint64_t b, Addends... addends)
{
if(b > std::numeric_limits<uint64_t>::max() - a.first)
return add_with_carry(std::pair<uint64_t, int>{b + a.first, 1 + a.second}, addends...);
else
return add_with_carry(std::pair<uint64_t, int>{b + a.first, a.second}, addends...);
}
template<typename... Addends>
std::pair<uint64_t, int> add_with_carry(uint64_t a, Addends... addends)
{
return add_with_carry(std::pair<uint64_t, int>{a, 0}, addends...);
}
auto [sum, carry] = add_with_carry(a, b, c, d, e);
There might be a more elegant way to implement this with fold expressions.
Caveat: You might overflow the carry int
if you have 2 billion variables in a call to add_with_carry
. Good luck with that though...