|
59 | 59 | #include "GameLogic/ScriptEngine.h" |
60 | 60 | #include "GameLogic/Weapon.h" |
61 | 61 |
|
| 62 | +#if __cplusplus >= 201611L |
| 63 | +#define USE_STD_FROM_CHARS_PARSING 1 |
| 64 | +#else |
| 65 | +#define USE_STD_FROM_CHARS_PARSING 0 |
| 66 | +#endif |
| 67 | + |
| 68 | +#if USE_STD_FROM_CHARS_PARSING |
| 69 | +#include <charconv> |
| 70 | +#include <string_view> |
| 71 | +#include <type_traits> |
| 72 | +#endif |
62 | 73 |
|
63 | 74 | /////////////////////////////////////////////////////////////////////////////////////////////////// |
64 | 75 | // PRIVATE DATA /////////////////////////////////////////////////////////////////////////////////// |
@@ -1624,40 +1635,86 @@ void INI::initFromINIMulti( void *what, const MultiIniFieldParse& parseTableList |
1624 | 1635 | return TheScienceStore->friend_lookupScience( token ); |
1625 | 1636 | } |
1626 | 1637 |
|
| 1638 | +#if USE_STD_FROM_CHARS_PARSING |
| 1639 | + |
| 1640 | +template <typename Type> |
| 1641 | +Type scanType(std::string_view token) |
| 1642 | +{ |
| 1643 | + // TheSuperHackers @info std::from_chars cannot parse "-1" as uint32 so the result needs to be int64 for integers. |
| 1644 | + std::conditional_t<std::is_integral_v<Type>, Int64, Real> result{}; |
| 1645 | + const auto [ptr, ec] = std::from_chars(token.data(), token.data() + token.size(), result); |
| 1646 | + |
| 1647 | + if (ec != std::errc{}) |
| 1648 | + { |
| 1649 | + throw INI_INVALID_DATA; |
| 1650 | + } |
| 1651 | + |
| 1652 | + return static_cast<Type>(result); |
| 1653 | +} |
| 1654 | + |
| 1655 | +#endif |
| 1656 | + |
1627 | 1657 | //------------------------------------------------------------------------------------------------- |
1628 | 1658 | /*static*/ Int INI::scanInt(const char* token) |
1629 | 1659 | { |
| 1660 | +#if USE_STD_FROM_CHARS_PARSING == 1 |
| 1661 | + return scanType<Int>(token); |
| 1662 | +#else |
1630 | 1663 | Int value; |
1631 | 1664 | if (sscanf( token, "%d", &value ) != 1) |
1632 | 1665 | throw INI_INVALID_DATA; |
| 1666 | + |
| 1667 | +#if USE_STD_FROM_CHARS_PARSING == -1 |
| 1668 | + if (value != scanType<Int>(token)) |
| 1669 | + throw INI_INVALID_DATA; |
| 1670 | +#endif |
| 1671 | + |
1633 | 1672 | return value; |
| 1673 | +#endif |
1634 | 1674 | } |
1635 | 1675 |
|
1636 | 1676 | //------------------------------------------------------------------------------------------------- |
1637 | 1677 | /*static*/ UnsignedInt INI::scanUnsignedInt(const char* token) |
1638 | 1678 | { |
| 1679 | +#if USE_STD_FROM_CHARS_PARSING == 1 |
| 1680 | + return scanType<UnsignedInt>(token); |
| 1681 | +#else |
1639 | 1682 | UnsignedInt value; |
1640 | 1683 | if (sscanf( token, "%u", &value ) != 1) // unsigned int is %u, not %d |
1641 | 1684 | throw INI_INVALID_DATA; |
| 1685 | + |
| 1686 | +#if USE_STD_FROM_CHARS_PARSING == -1 |
| 1687 | + if (value != scanType<UnsignedInt>(token)) |
| 1688 | + throw INI_INVALID_DATA; |
| 1689 | +#endif |
| 1690 | + |
1642 | 1691 | return value; |
| 1692 | +#endif |
1643 | 1693 | } |
1644 | 1694 |
|
1645 | 1695 | //------------------------------------------------------------------------------------------------- |
1646 | 1696 | /*static*/ Real INI::scanReal(const char* token) |
1647 | 1697 | { |
| 1698 | +#if USE_STD_FROM_CHARS_PARSING == 1 |
| 1699 | + return scanType<Real>(token); |
| 1700 | +#else |
1648 | 1701 | Real value; |
1649 | 1702 | if (sscanf( token, "%f", &value ) != 1) |
1650 | 1703 | throw INI_INVALID_DATA; |
| 1704 | + |
| 1705 | +#if USE_STD_FROM_CHARS_PARSING == -1 |
| 1706 | + if (value != scanType<Real>(token)) |
| 1707 | + throw INI_INVALID_DATA; |
| 1708 | +#endif |
| 1709 | + |
1651 | 1710 | return value; |
| 1711 | +#endif |
1652 | 1712 | } |
1653 | 1713 |
|
1654 | 1714 | //------------------------------------------------------------------------------------------------- |
1655 | 1715 | /*static*/ Real INI::scanPercentToReal(const char* token) |
1656 | 1716 | { |
1657 | | - Real value; |
1658 | | - if (sscanf( token, "%f", &value ) != 1) |
1659 | | - throw INI_INVALID_DATA; |
1660 | | - return value / 100.0f; |
| 1717 | + return scanReal(token) / 100.0f; |
1661 | 1718 | } |
1662 | 1719 |
|
1663 | 1720 | //------------------------------------------------------------------------------------------------- |
|
0 commit comments