namespace folly { namespace detail {
+/*
+ * Helper functions for how to perform division based on the desired
+ * return type.
+ */
+
+// For floating point input types, do floating point division
+template <typename ReturnType, typename ValueType>
+typename std::enable_if<std::is_floating_point<ValueType>::value,
+ ReturnType>::type
+avgHelper(ValueType sum, uint64_t count) {
+ if (count == 0) { return ReturnType(0); }
+ return static_cast<ReturnType>(sum / count);
+}
+
+// For floating point return types, do floating point division
+template <typename ReturnType, typename ValueType>
+typename std::enable_if<std::is_floating_point<ReturnType>::value &&
+ !std::is_floating_point<ValueType>::value,
+ ReturnType>::type
+avgHelper(ValueType sum, uint64_t count) {
+ if (count == 0) { return ReturnType(0); }
+ return static_cast<ReturnType>(sum) / count;
+}
+
+// For signed integer input types, do signed division
+template <typename ReturnType, typename ValueType>
+typename std::enable_if<!std::is_floating_point<ReturnType>::value &&
+ !std::is_floating_point<ValueType>::value &&
+ std::is_signed<ValueType>::value,
+ ReturnType>::type
+avgHelper(ValueType sum, uint64_t count) {
+ if (count == 0) { return ReturnType(0); }
+ return sum / static_cast<int64_t>(count);
+}
+
+// For unsigned integer input types, do unsigned division
+template <typename ReturnType, typename ValueType>
+typename std::enable_if<!std::is_floating_point<ReturnType>::value &&
+ !std::is_floating_point<ValueType>::value &&
+ std::is_unsigned<ValueType>::value,
+ ReturnType>::type
+avgHelper(ValueType sum, uint64_t count) {
+ if (count == 0) { return ReturnType(0); }
+ return sum / count;
+}
+
+
template<typename T>
struct Bucket {
public:
template <typename ReturnType>
ReturnType avg() const {
- return (count ?
- static_cast<ReturnType>(sum) / count :
- ReturnType(0));
+ return avgHelper<ReturnType>(sum, count);
}
ValueType sum;