feat(utils/misc): added a number of misc things (e.g. float roundoff compensated summation class)
This commit is contained in:
21
src/include/serif/utils/misc/compensated_sum.hpp
Normal file
21
src/include/serif/utils/misc/compensated_sum.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace serif::utils {
|
||||
/// Neumaier summation retains small terms when a scalar reduction contains cancellation.
|
||||
class CompensatedSum final {
|
||||
public:
|
||||
void add(const double value) {
|
||||
const double next = m_sum + value;
|
||||
m_correction += std::abs(m_sum) >= std::abs(value) ? (m_sum - next) + value : (value - next) + m_sum;
|
||||
m_sum = next;
|
||||
}
|
||||
|
||||
[[nodiscard]] double value() const { return m_sum + m_correction; }
|
||||
|
||||
private:
|
||||
double m_sum{0.0};
|
||||
double m_correction{0.0};
|
||||
};
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "serif/utils/misc/concepts/concat.hpp"
|
||||
#include "serif/utils/types/type_list.hpp"
|
||||
|
||||
namespace serif::utils::misc::concepts {
|
||||
// Might make sense to rename these to FlatMap or some such
|
||||
template <typename TypeList, template <typename> typename Descriptor>
|
||||
struct EnumerateTypes;
|
||||
|
||||
template <template <typename> typename Descriptor, typename... TypeTs>
|
||||
struct EnumerateTypes<types::TypeList<TypeTs...>, Descriptor> {
|
||||
using Type = ConcatT<Descriptor<TypeTs>...>;
|
||||
};
|
||||
|
||||
template <typename TypeList, template <typename> typename Descriptor>
|
||||
using EnumerateTypesT = EnumerateTypes<TypeList, Descriptor>::Type;
|
||||
}
|
||||
@@ -1,15 +1,10 @@
|
||||
#pragma once
|
||||
#include <exception>
|
||||
#include <type_traits>
|
||||
#include <string>
|
||||
|
||||
#include "serif/utils/misc/concepts/numeric.hpp"
|
||||
|
||||
namespace serif::utils::misc::concepts {
|
||||
template <typename ExceptionCandidate>
|
||||
concept IsException = std::is_base_of_v<std::exception, ExceptionCandidate>;
|
||||
|
||||
template <typename ExceptionCandidate, typename ErrorCode>
|
||||
concept IsExceptionWithErrorCode = IsException<ExceptionCandidate> &&
|
||||
std::constructible_from<ExceptionCandidate, ErrorCode, std::string>;
|
||||
}
|
||||
@@ -7,9 +7,6 @@ namespace serif::utils::misc::concepts {
|
||||
template <typename T>
|
||||
concept IsNumeric = std::integral<T> || std::floating_point<T>;
|
||||
|
||||
template <typename T>
|
||||
concept IsOrderable = std::totally_ordered<T>;
|
||||
|
||||
template <typename T>
|
||||
concept IsComparableToNumeric = std::totally_ordered_with<T, float> ||
|
||||
std::totally_ordered_with<T, double> ||
|
||||
@@ -20,7 +17,4 @@ namespace serif::utils::misc::concepts {
|
||||
|
||||
template <typename...Ts>
|
||||
concept SetOfOneOrTwo = (sizeof...(Ts) == 1) || (sizeof...(Ts) == 2);
|
||||
|
||||
template <typename EnumCandidate>
|
||||
concept IsEnum = std::is_enum_v<EnumCandidate>;
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include "serif/utils/misc/std_helper/cleaning.hpp"
|
||||
|
||||
namespace serif::utils::misc::traits {
|
||||
template <typename... Ts>
|
||||
constexpr bool all_unique_types_v = true;
|
||||
|
||||
|
||||
// This can be a bit confusing. Whats going on here is that !SameType<First, Rest> && ...
|
||||
// is preforming variadic folding. That is we check if First is the same as all types in
|
||||
// the rest type list. If First is the same as any of those this will eval to true and then be negated to false.
|
||||
// The only way for the first term (!SameType<First, Rest> && ...) to be true is if First is not the same as any of the types in Rest.
|
||||
// Then we recursively call all_unique_types_v<Rest...> to check the rest. This ensures that this is only true if
|
||||
// every single type in the type list is unique.
|
||||
/** @brief Compare each head with the remaining exact types without a pack-sized Boolean fold. */
|
||||
template <typename First, typename... Rest>
|
||||
constexpr bool all_unique_types_v<First, Rest...> = (!std_helper::SameType<First, Rest> && ...) && all_unique_types_v<Rest...>;
|
||||
|
||||
constexpr bool all_unique_types_v<First, Rest...> = [] {
|
||||
constexpr std::array<bool, sizeof...(Rest)> duplicates{std_helper::SameType<First, Rest>...};
|
||||
for (const bool duplicate : duplicates) {
|
||||
if (duplicate) { return false; }
|
||||
}
|
||||
return all_unique_types_v<Rest...>;
|
||||
}();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user