9#ifndef _SQUID_SRC_SQUIDMATH_H
10#define _SQUID_SRC_SQUIDMATH_H
27int intAverage(
const int,
const int,
int,
const int);
28double doubleAverage(
const double,
const double,
int,
const int);
37template <
typename T,
typename U>
39 std::is_unsigned<T>::value && std::is_unsigned<U>::value,
46template <
typename A,
typename B>
52 using AB =
typename std::common_type<A, B>::type;
54 (a >= 0 && b < 0) ? false :
55 (a < 0 && b >= 0) ?
true :
56 static_cast<AB
>(a) <
static_cast<AB
>(b);
64 static_assert(std::numeric_limits<T>::is_bounded,
"std::numeric_limits<T>::max() is meaningful");
65 static_assert(std::numeric_limits<T>::is_exact,
"no silent loss of precision");
66 static_assert(!std::is_enum<T>::value,
"no silent creation of non-enumerated values");
74template <typename S, typename A, typename B, std::enable_if_t<AllUnsigned<A,B>::value,
int> = 0>
78 static_assert(std::is_unsigned<A>::value,
"AllUnsigned dispatch worked for A");
79 static_assert(std::is_unsigned<B>::value,
"AllUnsigned dispatch worked for B");
81 AssertNaturalType<S>();
82 AssertNaturalType<A>();
83 AssertNaturalType<B>();
86 static_assert(std::is_same<
A,
decltype(+a)>::value,
"a will not be promoted");
87 static_assert(std::is_same<
B,
decltype(+b)>::value,
"b will not be promoted");
89 static_assert(std::is_unsigned<
decltype(a+b)>::value,
"a+b is unsigned");
93 using AB =
typename std::common_type<A, B>::type;
94 static_assert(std::is_same<AB, A>::value || std::is_same<AB, B>::value,
"no unexpected conversions");
95 static_assert(std::is_same<AB,
decltype(a+b)>::value,
"lossless assignment");
98 static_assert(std::numeric_limits<AB>::is_modulo,
"we can detect overflows");
103 std::optional<S>(sum) : std::optional<S>();
110template <typename S, typename A, typename B, std::enable_if_t<!AllUnsigned<A,B>::value,
int> = 0>
111std::optional<S>
constexpr
113 AssertNaturalType<S>();
114 AssertNaturalType<A>();
115 AssertNaturalType<B>();
118 static_assert(std::is_same<
A,
decltype(+a)>::value,
"a will not be promoted");
119 static_assert(std::is_same<
B,
decltype(+b)>::value,
"b will not be promoted");
125 (a < 0 || b < 0) ? std::optional<S>() :
138 std::optional<S>(a + b);
142template <
typename S,
typename T>
149 return IncreaseSumInternal<S>(+s, +t);
153template <
typename S,
typename T,
typename... Args>
165template <
typename SummationType,
typename... Args>
166std::optional<SummationType>
168 return IncreaseSum<SummationType>(0, args...);
174template <
typename S,
typename... Args>
184template <
typename Result,
typename Source>
188 return NaturalSum<Result>(s).value();
Result NaturalCast(const Source s)
S SetToNaturalSumOrMax(S &var, const Args... args)
std::optional< S > IncreaseSumInternal(const A a, const B b)
std::optional< SummationType > NaturalSum(const Args... args)
std::optional< S > IncreaseSum(const S s, const T t)
argument pack expansion termination for IncreaseSum<S, T, Args...>()
typename std::conditional< std::is_unsigned< T >::value &&std::is_unsigned< U >::value, std::true_type, std::false_type >::type AllUnsigned
constexpr void AssertNaturalType()
ensure that T is supported by NaturalSum() and friends
constexpr bool Less(const A a, const B b)
whether integer a is less than integer b, with correct overflow handling
squidaio_request_t * head
A const & max(A const &lhs, A const &rhs)
int intPercent(const int a, const int b)
double doubleAverage(const double, const double, int, const int)
double doublePercent(const double, const double)
int64_t int64Percent(const int64_t a, const int64_t b)
int intAverage(const int, const int, int, const int)