Add real-number version of parse_range

Also use it in the Lua API.
This commit is contained in:
Celtic Minstrel 2022-12-20 09:34:48 -05:00
parent 2b47e63e8b
commit 73a1b46bbf
3 changed files with 47 additions and 3 deletions

View file

@ -327,13 +327,20 @@ static int intf_str_format(lua_State* L)
/**
* Parses a range string of the form a-b into an interval pair
* Accepts the string "infinity" as representing a Very Large Number
* Arg 2: (optional) If true, parse as real numbers instead of integers
*/
static int intf_parse_range(lua_State* L)
{
const std::string str = luaL_checkstring(L, 1);
auto interval = utils::parse_range(str);
lua_pushnumber(L, interval.first);
lua_pushnumber(L, interval.second);
if(luaL_opt(L, lua_toboolean, 2, false)) {
auto interval = utils::parse_range_real(str);
lua_pushnumber(L, interval.first);
lua_pushnumber(L, interval.second);
} else {
auto interval = utils::parse_range(str);
lua_pushinteger(L, interval.first);
lua_pushinteger(L, interval.second);
}
return 2;
}

View file

@ -845,6 +845,29 @@ std::pair<int, int> parse_range(const std::string& str)
return res;
}
std::pair<double, double> parse_range_real(const std::string& str)
{
const std::string::const_iterator dash = std::find(str.begin(), str.end(), '-');
const std::string a(str.begin(), dash);
const std::string b = dash != str.end() ? std::string(dash + 1, str.end()) : a;
std::pair<double,double> res {0,0};
try {
if(b == "infinity") {
res = std::pair(std::stod(a), std::numeric_limits<double>::infinity());
} else {
res = std::pair(std::stod(a), std::stod(b));
}
if(res.second < res.first) {
res.second = res.first;
}
} catch(const std::invalid_argument&) {
ERR_GENERAL << "Invalid range: "<< str;
}
return res;
}
std::vector<std::pair<int, int>> parse_ranges(const std::string& str)
{
std::vector<std::pair<int, int>> to_return;
@ -855,6 +878,16 @@ std::vector<std::pair<int, int>> parse_ranges(const std::string& str)
return to_return;
}
std::vector<std::pair<double, double>> parse_ranges_real(const std::string& str)
{
std::vector<std::pair<double, double>> to_return;
for(const std::string& r : utils::split(str)) {
to_return.push_back(parse_range_real(r));
}
return to_return;
}
void ellipsis_truncate(std::string& str, const std::size_t size)
{
const std::size_t prev_size = str.length();

View file

@ -286,6 +286,10 @@ std::pair<int, int> parse_range(const std::string& str);
std::vector<std::pair<int, int>> parse_ranges(const std::string& str);
std::pair<double, double> parse_range_real(const std::string& str);
std::vector<std::pair<double, double>> parse_ranges_real(const std::string& str);
int apply_modifier(const int number, const std::string &amount, const int minimum = 0);
/** Add a "+" or replace the "-" par Unicode minus */