| 6729 | */ |
| 6730 | template<typename BasicJsonType, typename InputAdapterType> |
| 6731 | class lexer : public lexer_base<BasicJsonType> |
| 6732 | { |
| 6733 | using number_integer_t = typename BasicJsonType::number_integer_t; |
| 6734 | using number_unsigned_t = typename BasicJsonType::number_unsigned_t; |
| 6735 | using number_float_t = typename BasicJsonType::number_float_t; |
| 6736 | using string_t = typename BasicJsonType::string_t; |
| 6737 | using char_type = typename InputAdapterType::char_type; |
| 6738 | using char_int_type = typename std::char_traits<char_type>::int_type; |
| 6739 | |
| 6740 | public: |
| 6741 | using token_type = typename lexer_base<BasicJsonType>::token_type; |
| 6742 | |
| 6743 | explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept |
| 6744 | : ia(std::move(adapter)) |
| 6745 | , ignore_comments(ignore_comments_) |
| 6746 | , decimal_point_char(static_cast<char_int_type>(get_decimal_point())) |
| 6747 | {} |
| 6748 | |
| 6749 | // delete because of pointer members |
| 6750 | lexer(const lexer&) = delete; |
| 6751 | lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) |
| 6752 | lexer& operator=(lexer&) = delete; |
| 6753 | lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) |
| 6754 | ~lexer() = default; |
| 6755 | |
| 6756 | private: |
| 6757 | ///////////////////// |
| 6758 | // locales |
| 6759 | ///////////////////// |
| 6760 | |
| 6761 | /// return the locale-dependent decimal point |
| 6762 | JSON_HEDLEY_PURE |
| 6763 | static char get_decimal_point() noexcept |
| 6764 | { |
| 6765 | const auto* loc = localeconv(); |
| 6766 | JSON_ASSERT(loc != nullptr); |
| 6767 | return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point); |
| 6768 | } |
| 6769 | |
| 6770 | ///////////////////// |
| 6771 | // scan functions |
| 6772 | ///////////////////// |
| 6773 | |
| 6774 | /*! |
| 6775 | @brief get codepoint from 4 hex characters following `\u` |
| 6776 | |
| 6777 | For input "\u c1 c2 c3 c4" the codepoint is: |
| 6778 | (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4 |
| 6779 | = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0) |
| 6780 | |
| 6781 | Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f' |
| 6782 | must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The |
| 6783 | conversion is done by subtracting the offset (0x30, 0x37, and 0x57) |
| 6784 | between the ASCII value of the character and the desired integer value. |
| 6785 | |
| 6786 | @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or |
| 6787 | non-hex character) |
| 6788 | */ |