| 7414 | */ |
| 7415 | template<typename BasicJsonType, typename InputAdapterType> |
| 7416 | class lexer : public lexer_base<BasicJsonType> |
| 7417 | { |
| 7418 | using number_integer_t = typename BasicJsonType::number_integer_t; |
| 7419 | using number_unsigned_t = typename BasicJsonType::number_unsigned_t; |
| 7420 | using number_float_t = typename BasicJsonType::number_float_t; |
| 7421 | using string_t = typename BasicJsonType::string_t; |
| 7422 | using char_type = typename InputAdapterType::char_type; |
| 7423 | using char_int_type = typename std::char_traits<char_type>::int_type; |
| 7424 | |
| 7425 | public: |
| 7426 | using token_type = typename lexer_base<BasicJsonType>::token_type; |
| 7427 | |
| 7428 | explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept |
| 7429 | : ia(std::move(adapter)) |
| 7430 | , ignore_comments(ignore_comments_) |
| 7431 | , decimal_point_char(static_cast<char_int_type>(get_decimal_point())) |
| 7432 | {} |
| 7433 | |
| 7434 | // delete because of pointer members |
| 7435 | lexer(const lexer&) = delete; |
| 7436 | lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) |
| 7437 | lexer& operator=(lexer&) = delete; |
| 7438 | lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) |
| 7439 | ~lexer() = default; |
| 7440 | |
| 7441 | private: |
| 7442 | ///////////////////// |
| 7443 | // locales |
| 7444 | ///////////////////// |
| 7445 | |
| 7446 | /// return the locale-dependent decimal point |
| 7447 | JSON_HEDLEY_PURE |
| 7448 | static char get_decimal_point() noexcept |
| 7449 | { |
| 7450 | const auto* loc = localeconv(); |
| 7451 | JSON_ASSERT(loc != nullptr); |
| 7452 | return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point); |
| 7453 | } |
| 7454 | |
| 7455 | ///////////////////// |
| 7456 | // scan functions |
| 7457 | ///////////////////// |
| 7458 | |
| 7459 | /*! |
| 7460 | @brief get codepoint from 4 hex characters following `\u` |
| 7461 | |
| 7462 | For input "\u c1 c2 c3 c4" the codepoint is: |
| 7463 | (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4 |
| 7464 | = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0) |
| 7465 | |
| 7466 | Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f' |
| 7467 | must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The |
| 7468 | conversion is done by subtracting the offset (0x30, 0x37, and 0x57) |
| 7469 | between the ASCII value of the character and the desired integer value. |
| 7470 | |
| 7471 | @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or |
| 7472 | non-hex character) |
| 7473 | */ |