Files
salmanoff/include/user/intrinThresholdParams.h
T
hayodea 3dd627c91c Implement new intrin params; fix parseSynonyms
Previously parseSynonyms didn't properly return the last provided
synonym of the param in question, so fix it here to do that.
2026-04-03 23:14:23 -04:00

252 lines
5.8 KiB
C++

#ifndef SMO_INTRIN_THRESHOLD_PARAMS_H
#define SMO_INTRIN_THRESHOLD_PARAMS_H
#include <array>
#include <cstddef>
#include <cstdint>
#include <optional>
#include <stdexcept>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
namespace smo::intrin {
enum class ThresholdUnit
{
Percentage,
Absolute,
};
struct ParsedThresholdParam
{
int value;
ThresholdUnit unit;
std::string_view matchedName;
bool wasSpecified;
};
inline constexpr std::array<std::string_view, 2> kPosIntPcParamNames = {
"postrin-interest-percentage",
"postrin-interest-pc",
};
inline constexpr std::array<std::string_view, 3> kPosIntThrParamNames = {
"postrin-interest-threshold",
"postrin-interest-thresh",
"postrin-interest-thr",
};
inline constexpr std::array<std::string_view, 2> kNegIntPcParamNames = {
"negtrin-interest-percentage",
"negtrin-interest-pc",
};
inline constexpr std::array<std::string_view, 3> kNegIntThrParamNames = {
"negtrin-interest-threshold",
"negtrin-interest-thresh",
"negtrin-interest-thr",
};
inline constexpr std::array<std::string_view, 2> kPosDistPcParamNames = {
"postrin-distraction-percentage",
"postrin-distraction-pc",
};
inline constexpr std::array<std::string_view, 3> kPosDistThrParamNames = {
"postrin-distraction-threshold",
"postrin-distraction-thresh",
"postrin-distraction-thr",
};
inline constexpr std::array<std::string_view, 2> kNegDistPcParamNames = {
"negtrin-distraction-percentage",
"negtrin-distraction-pc",
};
inline constexpr std::array<std::string_view, 3> kNegDistThrParamNames = {
"negtrin-distraction-threshold",
"negtrin-distraction-thresh",
"negtrin-distraction-thr",
};
inline constexpr std::array<std::string_view, 8> kStupefactionPcParamNames = {
"postrin-stupefaction-percentage",
"postrin-stupefaction-pc",
"postrin-stupefying-percentage",
"postrin-stupefying-pc",
"stupefaction-percentage",
"stupefaction-pc",
"stupefying-percentage",
"stupefying-pc",
};
inline constexpr std::array<std::string_view, 12> kStupefactionThrParamNames = {
"postrin-stupefaction-threshold",
"postrin-stupefaction-thresh",
"postrin-stupefaction-thr",
"postrin-stupefying-threshold",
"postrin-stupefying-thresh",
"postrin-stupefying-thr",
"stupefaction-threshold",
"stupefaction-thresh",
"stupefaction-thr",
"stupefying-threshold",
"stupefying-thresh",
"stupefying-thr",
};
inline constexpr std::array<std::string_view, 4> kIntolerablePcParamNames = {
"negtrin-intolerable-percentage",
"negtrin-intolerable-pc",
"intolerable-percentage",
"intolerable-pc",
};
inline constexpr std::array<std::string_view, 6> kIntolerableThrParamNames = {
"negtrin-intolerable-threshold",
"negtrin-intolerable-thresh",
"negtrin-intolerable-thr",
"intolerable-threshold",
"intolerable-thresh",
"intolerable-thr",
};
inline constexpr std::array<std::string_view, 10> kForbiddenUnitlessIntrinParamNames = {
"postrin-interest",
"negtrin-interest",
"postrin-distraction",
"negtrin-distraction",
"postrin-stupefaction",
"postrin-stupefying",
"stupefaction",
"stupefying",
"negtrin-intolerable",
"intolerable",
};
template <std::size_t N>
bool arrayContains(
const std::array<std::string_view, N>& names,
std::string_view candidate)
{
for (const auto& name : names) {
if (name == candidate) { return true; }
}
return false;
}
template <typename NameCollectionT>
bool namesContain(
const NameCollectionT& names,
std::string_view candidate)
{
for (const auto& name : names) {
if (name == candidate) { return true; }
}
return false;
}
inline void validateNoForbiddenUnitlessIntrinParams(
const std::vector<std::pair<std::string, std::string>>& params)
{
for (const auto& [name, value] : params)
{
(void)value;
if (arrayContains(kForbiddenUnitlessIntrinParamNames, name))
{
throw std::runtime_error(
"Intrinsic threshold param '" + name
+ "' is invalid without a unit suffix. Use a "
"'-percentage'/'-pc' or '-threshold'/'-thresh'/'-thr' variant.");
}
}
}
inline std::optional<std::pair<std::string_view, int>> findLastMatchingIntParam(
const std::vector<std::pair<std::string, std::string>>& params,
const auto& synonymNames)
{
for (auto paramIt = params.rbegin(); paramIt != params.rend(); ++paramIt)
{
const auto& [name, value] = *paramIt;
if (!namesContain(synonymNames, name))
{ continue; }
try {
return std::pair<std::string_view, int>(name, std::stoi(value));
}
catch (const std::exception& e)
{
throw std::runtime_error(
"Failed to parse '" + name + "' param value '" + value
+ "' as integer: " + e.what());
}
}
return std::nullopt;
}
inline ParsedThresholdParam parseOptionalThresholdParam(
const std::vector<std::pair<std::string, std::string>>& params,
const auto& percentageNames,
const auto& absoluteNames,
int defaultValue,
ThresholdUnit defaultUnit)
{
for (auto paramIt = params.rbegin(); paramIt != params.rend(); ++paramIt)
{
const auto& [name, value] = *paramIt;
ThresholdUnit unit;
if (namesContain(percentageNames, name))
{ unit = ThresholdUnit::Percentage; }
else if (namesContain(absoluteNames, name))
{ unit = ThresholdUnit::Absolute; }
else
{ continue; }
try
{
return ParsedThresholdParam{
.value = std::stoi(value),
.unit = unit,
.matchedName = name,
.wasSpecified = true,
};
}
catch (const std::exception& e)
{
throw std::runtime_error(
"Failed to parse '" + name + "' param value '" + value
+ "' as integer: " + e.what());
}
}
return ParsedThresholdParam{
.value = defaultValue,
.unit = defaultUnit,
.matchedName = {},
.wasSpecified = false,
};
}
inline uint32_t resolveThresholdValue(
const ParsedThresholdParam& param,
size_t percentageBase)
{
if (param.unit == ThresholdUnit::Percentage) {
return static_cast<uint32_t>((percentageBase * param.value) / 100);
}
return static_cast<uint32_t>(param.value);
}
} // namespace smo::intrin
#endif // SMO_INTRIN_THRESHOLD_PARAMS_H