feat(quadrature): quadrature system brought over

Ported and dramatically cleaned up the quadrature system. This includes centralizing all field definitions
This commit is contained in:
2026-09-19 07:35:57 -04:00
parent 7b4f30d945
commit c44584c1e7
75 changed files with 8936 additions and 172 deletions

View File

@@ -0,0 +1,25 @@
#pragma once
#include "serif/utils/types/type_list.hpp"
namespace serif::utils::misc::concepts {
template <typename... Lists>
struct Concat;
template <>
struct Concat<> {
using Type = types::TypeList<>;
};
template <typename... Ts>
struct Concat<types::TypeList<Ts...>> {
using Type = types::TypeList<Ts...>;
};
template <typename... LhsTs, typename... RhsTs, typename... Rest>
struct Concat<types::TypeList<LhsTs...>, types::TypeList<RhsTs...>, Rest...> {
using Type = typename Concat<types::TypeList<LhsTs..., RhsTs...>, Rest...>::Type;
};
template <typename... Lists>
using ConcatT = Concat<Lists...>::Type;
}

View File

@@ -0,0 +1,18 @@
#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;
}

View File

@@ -0,0 +1,37 @@
#pragma once
#include <type_traits>
#include "serif/utils/types/type_list.hpp"
namespace serif::utils::misc::concepts {
template <typename T, typename List>
struct Prepend;
template <typename T, typename... Ts>
struct Prepend<T, types::TypeList<Ts...>> {
using Type = types::TypeList<T, Ts...>;
};
template <typename T, typename List>
using PrependT = Prepend<T, List>::Type;
template <typename List, template <typename> typename Predicate>
struct Filter;
template <template <typename> typename Predicate>
struct Filter<types::TypeList<>, Predicate> {
using Type = types::TypeList<>;
};
template <typename Head, typename... Tail, template <typename> typename Predicate>
struct Filter<types::TypeList<Head, Tail...>, Predicate> {
private:
using FilteredTail = Filter<types::TypeList<Tail...>, Predicate>::Type;
public:
using Type = std::conditional_t<Predicate<Head>::value, PrependT<Head, FilteredTail>, FilteredTail>;
};
template <typename List, template <typename> typename Predicate>
using FilterT = Filter<List, Predicate>::Type;
}

View File

@@ -5,39 +5,36 @@
#include "serif/utils/misc/concepts/numeric.hpp"
#include "serif/utils/misc/concepts/exceptions.hpp"
#include "serif/utils/error/errors.hpp"
namespace serif::utils::misc {
template <typename ExceptionType, concepts::IsNumeric Scalar, concepts::IsEnum ErrorCode>
requires concepts::IsExceptionWithErrorCode<ExceptionType, ErrorCode>
void validate_finite(const Scalar value, ErrorCode error_code) {
template <typename ExceptionType, errors::SERiFErrorCode ErrorCode, concepts::IsNumeric Scalar>
void validate_finite(const Scalar value) {
if (!std::isfinite(value)) {
throw ExceptionType(error_code, std::format("The value must be finite. Instead a value of {} has been provided", value));
errors::serif_error<ExceptionType, ErrorCode>("The value must be finite. Instead a value of {} has been provided", value);
};
}
template <typename ExceptionType, concepts::IsComparableToNumeric Scalar, concepts::IsEnum ErrorCode>
requires concepts::IsExceptionWithErrorCode<ExceptionType, ErrorCode>
void validate_greater_than(const Scalar value, const Scalar predicate, ErrorCode error_code) {
validate_finite<ExceptionType>(value, error_code);
template <typename ExceptionType, errors::SERiFErrorCode ErrorCode, concepts::IsComparableToNumeric Scalar>
void validate_greater_than(const Scalar value, const Scalar predicate) {
validate_finite<ExceptionType, ErrorCode>(value);
if (value < predicate) {
throw ExceptionType(error_code, std::format("The value must be finite and greater than {}. While the value is finite it is also less than {}. A value of {} has been provided", predicate, predicate, value));
errors::serif_error<ExceptionType, ErrorCode>("The value must be finite and greater than {}. While the value is finite it is also less than {}. A value of {} has been provided", predicate, predicate, value);
};
}
template <typename ExceptionType, concepts::IsComparableToNumeric Scalar, concepts::IsEnum ErrorCode>
requires concepts::IsExceptionWithErrorCode<ExceptionType, ErrorCode>
void validate_less_than(const Scalar value, const Scalar predicate, ErrorCode error_code) {
validate_finite<ExceptionType>(value, error_code);
template <typename ExceptionType, errors::SERiFErrorCode ErrorCode, concepts::IsComparableToNumeric Scalar>
void validate_less_than(const Scalar value, const Scalar predicate) {
validate_finite<ExceptionType, ErrorCode>(value);
if (value > predicate) {
throw ExceptionType(error_code, std::format("The value must be finite and less than {}. While the value is finite it is also greater than {}. A value of {} has been provided", predicate, predicate, value));
errors::serif_error<ExceptionType, ErrorCode>("The value must be finite and less than {}. While the value is finite it is also greater than {}. A value of {} has been provided", predicate, predicate, value);
};
}
template <typename ExceptionType, concepts::IsComparableToNumeric Scalar, concepts::IsEnum ErrorCode>
requires concepts::IsExceptionWithErrorCode<ExceptionType, ErrorCode>
void validate_nonnegativity(const Scalar value, ErrorCode error_code) {
validate_finite<ExceptionType>(value, error_code);
validate_greater_than<ExceptionType>(value,static_cast<Scalar>(0), error_code);
template <typename ExceptionType, errors::SERiFErrorCode ErrorCode, concepts::IsComparableToNumeric Scalar>
void validate_nonnegativity(const Scalar value) {
validate_finite<ExceptionType, ErrorCode>(value);
validate_greater_than<ExceptionType, ErrorCode>(value,static_cast<Scalar>(0));
}

View File

@@ -0,0 +1,74 @@
#pragma once
#include <string_view>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
namespace serif::utils::misc::terminal {
enum class ANSIColors : int {
BLACK = 30,
RED = 31,
GREEN = 32,
YELLOW = 33,
BLUE = 34,
MAGENTA = 35,
CYAN = 36,
WHITE = 37,
BRIGHT_BLACK = 90,
BRIGHT_RED = 91,
BRIGHT_GREEN = 92,
RESET = 0
};
consteval std::string_view resolve_ansi_color(const ANSIColors color) noexcept {
switch (color) {
case ANSIColors::BLACK: return "\033[30m";
case ANSIColors::RED: return "\033[31m";
case ANSIColors::GREEN: return "\033[32m";
case ANSIColors::YELLOW: return "\033[33m";
case ANSIColors::BLUE: return "\033[34m";
case ANSIColors::MAGENTA: return "\033[35m";
case ANSIColors::CYAN: return "\033[36m";
case ANSIColors::WHITE: return "\033[37m";
case ANSIColors::BRIGHT_BLACK: return "\033[90m";
case ANSIColors::BRIGHT_RED: return "\033[91m";
case ANSIColors::BRIGHT_GREEN: return "\033[92m";
case ANSIColors::RESET: return "\033[0m";
}
std::unreachable();
}
constexpr std::string_view a_black = resolve_ansi_color(ANSIColors::BLACK);
constexpr std::string_view a_red = resolve_ansi_color(ANSIColors::RED);
constexpr std::string_view a_green = resolve_ansi_color(ANSIColors::GREEN);
constexpr std::string_view a_yellow = resolve_ansi_color(ANSIColors::YELLOW);
constexpr std::string_view a_blue = resolve_ansi_color(ANSIColors::BLUE);
constexpr std::string_view a_magenta = resolve_ansi_color(ANSIColors::MAGENTA);
constexpr std::string_view a_cyan = resolve_ansi_color(ANSIColors::CYAN);
constexpr std::string_view a_white = resolve_ansi_color(ANSIColors::WHITE);
constexpr std::string_view a_bright_black = resolve_ansi_color(ANSIColors::BRIGHT_BLACK);
constexpr std::string_view a_bright_red = resolve_ansi_color(ANSIColors::BRIGHT_RED);
constexpr std::string_view a_bright_green = resolve_ansi_color(ANSIColors::BRIGHT_GREEN);
constexpr std::string_view a_reset = resolve_ansi_color(ANSIColors::RESET);
inline bool supports_ansi(std::FILE* stream = stdout) noexcept {
if (const char* noColor = std::getenv("NO_COLOR");
noColor != nullptr && *noColor != '\0') {
return false;
}
if (::isatty(::fileno(stream)) == 0) {
return false;
}
const char* term = std::getenv("TERM");
if (term == nullptr) {
return false;
}
return std::string_view(term) != "dumb";
}
}