#pragma once #include template Result safe_add(T a, T b) { T result; if (__builtin_add_overflow(a, b, &result)) return err(EOVERFLOW); return result; } template Result safe_sub(T a, T b) { T result; if (__builtin_sub_overflow(a, b, &result)) return err(EOVERFLOW); return result; } template Result safe_mul(T a, T b) { T result; if (__builtin_mul_overflow(a, b, &result)) return err(EOVERFLOW); return result; } template bool add_will_overflow(T a, T b) { #ifdef __GNUC__ return __builtin_add_overflow_p(a, b, (T)0); #else return safe_add(a, b).has_error(); #endif } template bool sub_will_overflow(T a, T b) { #ifdef __GNUC__ return __builtin_sub_overflow_p(a, b, (T)0); #else return safe_sub(a, b).has_error(); #endif } template bool mul_will_overflow(T a, T b) { #ifdef __GNUC__ return __builtin_mul_overflow_p(a, b, (T)0); #else return safe_mul(a, b).has_error(); #endif }