eden-miror/src/common/overflow.h
lizzie dfaecdf68c
[cmake] enable clang-cl and WoA builds (#348)
Compilation and CMake fixes for both Windows on ARM and clang-cl, meaning Windows can now be built on both MSVC and clang on both amd64 and aarch64.

Compiling on clang is *dramatically* faster so this should be useful for CI.

Co-authored-by: crueter <crueter@eden-emu.dev>
Co-authored-by: crueter <crueter@crueter.xyz>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/348
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:37:58 -04:00

40 lines
954 B
C++

// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <algorithm>
#include <type_traits>
#include "bit_cast.h"
namespace Common {
template <typename T>
requires(std::is_integral_v<T> && std::is_signed_v<T>)
inline T WrappingAdd(T lhs, T rhs) {
using U = std::make_unsigned_t<T>;
U lhs_u = BitCast<U>(lhs);
U rhs_u = BitCast<U>(rhs);
return BitCast<T>(lhs_u + rhs_u);
}
template <typename T>
requires(std::is_integral_v<T> && std::is_signed_v<T>)
inline bool CanAddWithoutOverflow(T lhs, T rhs) {
#ifdef _MSC_VER
if (lhs >= 0 && rhs >= 0) {
return WrappingAdd(lhs, rhs) >= (std::max)(lhs, rhs);
} else if (lhs < 0 && rhs < 0) {
return WrappingAdd(lhs, rhs) <= (std::min)(lhs, rhs);
} else {
return true;
}
#else
T res;
return !__builtin_add_overflow(lhs, rhs, &res);
#endif
}
} // namespace Common