| 7481 | */ |
| 7482 | template<typename BasicJsonType, typename InputAdapterType> |
| 7483 | class lexer : public lexer_base<BasicJsonType> |
| 7484 | { |
| 7485 | using number_integer_t = typename BasicJsonType::number_integer_t; |
| 7486 | using number_unsigned_t = typename BasicJsonType::number_unsigned_t; |
| 7487 | using number_float_t = typename BasicJsonType::number_float_t; |
| 7488 | using string_t = typename BasicJsonType::string_t; |
| 7489 | using char_type = typename InputAdapterType::char_type; |
| 7490 | using char_int_type = typename char_traits<char_type>::int_type; |
| 7491 | |
| 7492 | public: |
| 7493 | using token_type = typename lexer_base<BasicJsonType>::token_type; |
| 7494 | |
| 7495 | explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept |
| 7496 | : ia(std::move(adapter)) |
| 7497 | , ignore_comments(ignore_comments_) |
| 7498 | , decimal_point_char(static_cast<char_int_type>(get_decimal_point())) |
| 7499 | {} |
| 7500 | |
| 7501 | // delete because of pointer members |
| 7502 | lexer(const lexer&) = delete; |
| 7503 | lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) |
| 7504 | lexer& operator=(lexer&) = delete; |
| 7505 | lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) |
| 7506 | ~lexer() = default; |
| 7507 | |
| 7508 | private: |
| 7509 | ///////////////////// |
| 7510 | // locales |
| 7511 | ///////////////////// |
| 7512 | |
| 7513 | /// return the locale-dependent decimal point |
| 7514 | JSON_HEDLEY_PURE |
| 7515 | static char get_decimal_point() noexcept |
| 7516 | { |
| 7517 | const auto* loc = localeconv(); |
| 7518 | JSON_ASSERT(loc != nullptr); |
| 7519 | return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point); |
| 7520 | } |
| 7521 | |
| 7522 | ///////////////////// |
| 7523 | // scan functions |
| 7524 | ///////////////////// |
| 7525 | |
| 7526 | /*! |
| 7527 | @brief get codepoint from 4 hex characters following `\u` |
| 7528 | |
| 7529 | For input "\u c1 c2 c3 c4" the codepoint is: |
| 7530 | (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4 |
| 7531 | = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0) |
| 7532 | |
| 7533 | Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f' |
| 7534 | must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The |
| 7535 | conversion is done by subtracting the offset (0x30, 0x37, and 0x57) |
| 7536 | between the ASCII value of the character and the desired integer value. |
| 7537 | |
| 7538 | @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or |
| 7539 | non-hex character) |
| 7540 | */ |