#ifndef FZ_SATURATED_ARITHMETIC_HPP
#define FZ_SATURATED_ARITHMETIC_HPP

#include <type_traits>
#include <limits>

namespace fz {

template <typename T>
inline T mul_sat(T a, T b) {
	static_assert(std::is_integral<T>::value, "Only integral types are supported");

	T result;

#ifdef __GNUC__
	if (__builtin_mul_overflow(a, b, &result)) {
		return (a > 0) == (b > 0) ? std::numeric_limits<T>::max() : std::numeric_limits<T>::min();
	}
#else
#	error "Your compiler is not supported"
#endif

	return result;
}

}

#endif // FZ_SATURATED_ARITHMETIC_HPP
