rapidyaml 0.14.0
parse and emit YAML, and do it fast
Loading...
Searching...
No Matches
overflows: does a number string overflow a type

Functions

template<class T>
auto c4::overflows (csubstr str) noexcept -> typename std::enable_if< std::is_unsigned< T >::value, bool >::type
 Test if the following string would overflow when converted to associated integral types; this function is dispatched with SFINAE to handle differently signed and unsigned types.
template<class T>
auto c4::overflows (csubstr str) noexcept -> typename std::enable_if< std::is_signed< T >::value, bool >::type
 Test if the following string would overflow when converted to associated integral types; this function is dispatched with SFINAE to handle differently signed and unsigned types.

Detailed Description

Function Documentation

◆ overflows() [1/2]

template<class T>
auto c4::overflows ( csubstr str) ->typenamestd::enable_if< std::is_unsigned< T >::value, bool >::type
noexcept

Test if the following string would overflow when converted to associated integral types; this function is dispatched with SFINAE to handle differently signed and unsigned types.

Returns
true if number will overflow, false if it fits (or doesn't parse)
See also
Check read for overflow for format specifiers to enforce no-overflow reads

Definition at line 1654 of file charconv.hpp.

1656{
1657 C4_STATIC_ASSERT(std::is_integral<T>::value);
1658
1659 if(C4_UNLIKELY(str.len == 0))
1660 {
1661 return false;
1662 }
1663 else if(str.str[0] == '0')
1664 {
1665 if (str.len == 1)
1666 return false;
1667 switch (str.str[1])
1668 {
1669 case 'x':
1670 case 'X':
1671 {
1672 size_t fno = str.first_not_of('0', 2);
1673 if (fno == csubstr::npos)
1674 return false;
1675 return !(str.len <= fno + (sizeof(T) * 2));
1676 }
1677 case 'b':
1678 case 'B':
1679 {
1680 size_t fno = str.first_not_of('0', 2);
1681 if (fno == csubstr::npos)
1682 return false;
1683 return !(str.len <= fno +(sizeof(T) * 8));
1684 }
1685 case 'o':
1686 case 'O':
1687 {
1688 size_t fno = str.first_not_of('0', 2);
1689 if(fno == csubstr::npos)
1690 return false;
1691 return detail::charconv_digits<T>::is_oct_overflow(str.sub(fno));
1692 }
1693 default:
1694 {
1695 size_t fno = str.first_not_of('0', 1);
1696 if(fno == csubstr::npos)
1697 return false;
1698 return detail::check_overflow(str.sub(fno), detail::charconv_digits<T>::max_value_dec());
1699 }
1700 }
1701 }
1702 else if(C4_UNLIKELY(str.str[0] == '-'))
1703 {
1704 return true;
1705 }
1706 else
1707 {
1708 return detail::check_overflow(str, detail::charconv_digits<T>::max_value_dec());
1709 }
1710}
size_t first_not_of(const C c) const
Definition substr.hpp:994
size_t len
the length of the substring
Definition substr.hpp:218
basic_substring sub(size_t first) const noexcept
return [first,len[
Definition substr.hpp:503
C * str
a restricted pointer to the first character of the substring
Definition substr.hpp:216

◆ overflows() [2/2]

template<class T>
auto c4::overflows ( csubstr str) ->typenamestd::enable_if< std::is_signed< T >::value, bool >::type
noexcept

Test if the following string would overflow when converted to associated integral types; this function is dispatched with SFINAE to handle differently signed and unsigned types.

Returns
true if number will overflow, false if it fits (or doesn't parse)
See also
Check read for overflow for format specifiers to enforce no-overflow reads

Definition at line 1721 of file charconv.hpp.

1723{
1724 C4_STATIC_ASSERT(std::is_integral<T>::value);
1725 if(C4_UNLIKELY(str.len == 0))
1726 return false;
1727 if(str.str[0] == '-')
1728 {
1729 if(str.str[1] == '0')
1730 {
1731 if(str.len == 2)
1732 return false;
1733 switch(str.str[2])
1734 {
1735 case 'x':
1736 case 'X':
1737 {
1738 size_t fno = str.first_not_of('0', 3);
1739 if (fno == csubstr::npos)
1740 return false;
1741 return detail::check_overflow(str.sub(fno), detail::charconv_digits<T>::min_value_hex());
1742 }
1743 case 'b':
1744 case 'B':
1745 {
1746 size_t fno = str.first_not_of('0', 3);
1747 if (fno == csubstr::npos)
1748 return false;
1749 return detail::check_overflow(str.sub(fno), detail::charconv_digits<T>::min_value_bin());
1750 }
1751 case 'o':
1752 case 'O':
1753 {
1754 size_t fno = str.first_not_of('0', 3);
1755 if(fno == csubstr::npos)
1756 return false;
1757 return detail::check_overflow(str.sub(fno), detail::charconv_digits<T>::min_value_oct());
1758 }
1759 default:
1760 {
1761 size_t fno = str.first_not_of('0', 2);
1762 if(fno == csubstr::npos)
1763 return false;
1764 return detail::check_overflow(str.sub(fno), detail::charconv_digits<T>::min_value_dec());
1765 }
1766 }
1767 }
1768 else
1769 {
1770 return detail::check_overflow(str.sub(1), detail::charconv_digits<T>::min_value_dec());
1771 }
1772 }
1773 else if(str.str[0] == '0')
1774 {
1775 if (str.len == 1)
1776 return false;
1777 switch(str.str[1])
1778 {
1779 case 'x':
1780 case 'X':
1781 {
1782 size_t fno = str.first_not_of('0', 2);
1783 if (fno == csubstr::npos)
1784 return false;
1785 const size_t len = str.len - fno;
1786 return !((len < sizeof (T) * 2) || (len == sizeof(T) * 2 && str.str[fno] <= '7'));
1787 }
1788 case 'b':
1789 case 'B':
1790 {
1791 size_t fno = str.first_not_of('0', 2);
1792 if (fno == csubstr::npos)
1793 return false;
1794 return !(str.len <= fno + (sizeof(T) * 8 - 1));
1795 }
1796 case 'o':
1797 case 'O':
1798 {
1799 size_t fno = str.first_not_of('0', 2);
1800 if(fno == csubstr::npos)
1801 return false;
1802 return detail::charconv_digits<T>::is_oct_overflow(str.sub(fno));
1803 }
1804 default:
1805 {
1806 size_t fno = str.first_not_of('0', 1);
1807 if(fno == csubstr::npos)
1808 return false;
1809 return detail::check_overflow(str.sub(fno), detail::charconv_digits<T>::max_value_dec());
1810 }
1811 }
1812 }
1813 else
1814 {
1815 return detail::check_overflow(str, detail::charconv_digits<T>::max_value_dec());
1816 }
1817}