Fast Methods for Cosmological Simulations
FastSim serves as a tool for quick N-body simulations in modified gravity.
nlohmann::detail::lexer< BasicJsonType > Class Template Reference

lexical analysis More...

#include <json.hpp>

Collaboration diagram for nlohmann::detail::lexer< BasicJsonType >:

Public Types

enum  token_type {
  token_type::uninitialized, token_type::literal_true, token_type::literal_false, token_type::literal_null,
  token_type::value_string, token_type::value_unsigned, token_type::value_integer, token_type::value_float,
  token_type::begin_array, token_type::begin_object, token_type::end_array, token_type::end_object,
  token_type::name_separator, token_type::value_separator, token_type::parse_error, token_type::end_of_input,
  token_type::literal_or_value
}
 token types for the parser More...
 

Public Member Functions

 lexer (detail::input_adapter_t &&adapter)
 
 lexer (const lexer &)=delete
 
 lexer (lexer &&)=delete
 
lexeroperator= (lexer &)=delete
 
lexeroperator= (lexer &&)=delete
 
 ~lexer ()=default
 
constexpr number_integer_t get_number_integer () const noexcept
 return integer value More...
 
constexpr number_unsigned_t get_number_unsigned () const noexcept
 return unsigned integer value More...
 
constexpr number_float_t get_number_float () const noexcept
 return floating-point value More...
 
string_tget_string ()
 return current string value (implicitly resets the token; useful only once) More...
 
constexpr position_t get_position () const noexcept
 return position of last read token More...
 
std::string get_token_string () const
 
constexpr const char * get_error_message () const noexcept
 return syntax error message More...
 
bool skip_bom ()
 skip the UTF-8 byte order mark More...
 
token_type scan ()
 

Static Public Member Functions

static const char * token_type_name (const token_type t) noexcept
 return name of values of type token_type (only used for errors) More...
 

Private Types

using number_integer_t = typename BasicJsonType::number_integer_t
 
using number_unsigned_t = typename BasicJsonType::number_unsigned_t
 
using number_float_t = typename BasicJsonType::number_float_t
 
using string_t = typename BasicJsonType::string_t
 

Private Member Functions

int get_codepoint ()
 get codepoint from 4 hex characters following \u More...
 
bool next_byte_in_range (std::initializer_list< int > ranges)
 check if the next byte(s) are inside a given range More...
 
token_type scan_string ()
 scan a string literal More...
 
token_type scan_number ()
 scan a number literal More...
 
token_type scan_literal (const char *literal_text, const std::size_t length, token_type return_type)
 
void reset () noexcept
 reset token_buffer; current character is beginning of token More...
 
std::char_traits< char >::int_type get ()
 
void unget ()
 unget current character (read it again on next get) More...
 
void add (int c)
 add a character to token_buffer More...
 

Static Private Member Functions

static char get_decimal_point () noexcept
 return the locale-dependent decimal point More...
 
static void strtof (float &f, const char *str, char **endptr) noexcept
 
static void strtof (double &f, const char *str, char **endptr) noexcept
 
static void strtof (long double &f, const char *str, char **endptr) noexcept
 

Private Attributes

detail::input_adapter_t ia = nullptr
 input adapter More...
 
std::char_traits< char >::int_type current = std::char_traits<char>::eof()
 the current character More...
 
bool next_unget = false
 whether the next get() call should just return current More...
 
position_t position
 the start position of the current token More...
 
std::vector< char > token_string {}
 raw input token string (for error messages) More...
 
string_t token_buffer {}
 buffer for variable-length tokens (numbers, strings) More...
 
const char * error_message = ""
 a description of occurred lexer errors More...
 
number_integer_t value_integer = 0
 
number_unsigned_t value_unsigned = 0
 
number_float_t value_float = 0
 
const char decimal_point_char = '.'
 the decimal point More...
 

Detailed Description

template<typename BasicJsonType>
class nlohmann::detail::lexer< BasicJsonType >

lexical analysis

This class organizes the lexical analysis during JSON deserialization.

Definition at line 2475 of file json.hpp.

Member Typedef Documentation

template<typename BasicJsonType >
using nlohmann::detail::lexer< BasicJsonType >::number_float_t = typename BasicJsonType::number_float_t
private

Definition at line 2479 of file json.hpp.

template<typename BasicJsonType >
using nlohmann::detail::lexer< BasicJsonType >::number_integer_t = typename BasicJsonType::number_integer_t
private

Definition at line 2477 of file json.hpp.

template<typename BasicJsonType >
using nlohmann::detail::lexer< BasicJsonType >::number_unsigned_t = typename BasicJsonType::number_unsigned_t
private

Definition at line 2478 of file json.hpp.

template<typename BasicJsonType >
using nlohmann::detail::lexer< BasicJsonType >::string_t = typename BasicJsonType::string_t
private

Definition at line 2480 of file json.hpp.

Member Enumeration Documentation

template<typename BasicJsonType >
enum nlohmann::detail::lexer::token_type
strong

token types for the parser

Enumerator
uninitialized 

indicating the scanner is uninitialized

literal_true 

the true literal

literal_false 

the false literal

literal_null 

the null literal

value_string 

a string – use get_string() for actual value

value_unsigned 

an unsigned integer – use get_number_unsigned() for actual value

value_integer 

a signed integer – use get_number_integer() for actual value

value_float 

an floating point number – use get_number_float() for actual value

begin_array 

the character for array begin [

begin_object 

the character for object begin {

end_array 

the character for array end ]

end_object 

the character for object end }

name_separator 

the name separator :

value_separator 

the value separator ,

parse_error 

indicating a parse error

end_of_input 

indicating the end of the input buffer

literal_or_value 

a literal or the begin of a value (only for diagnostics)

Definition at line 2484 of file json.hpp.

2485  {
2486  uninitialized,
2487  literal_true,
2488  literal_false,
2489  literal_null,
2490  value_string,
2491  value_unsigned,
2492  value_integer,
2493  value_float,
2494  begin_array,
2495  begin_object,
2496  end_array,
2497  end_object,
2498  name_separator,
2499  value_separator,
2500  parse_error,
2501  end_of_input,
2502  literal_or_value
2503  };
number_unsigned_t value_unsigned
Definition: json.hpp:3945
number_integer_t value_integer
Definition: json.hpp:3944
number_float_t value_float
Definition: json.hpp:3946

Constructor & Destructor Documentation

template<typename BasicJsonType >
nlohmann::detail::lexer< BasicJsonType >::lexer ( detail::input_adapter_t &&  adapter)
inlineexplicit

Definition at line 2549 of file json.hpp.

2550  : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
detail::input_adapter_t ia
input adapter
Definition: json.hpp:3923
const char decimal_point_char
the decimal point
Definition: json.hpp:3949
static char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition: json.hpp:2565
template<typename BasicJsonType >
nlohmann::detail::lexer< BasicJsonType >::lexer ( const lexer< BasicJsonType > &  )
delete
template<typename BasicJsonType >
nlohmann::detail::lexer< BasicJsonType >::lexer ( lexer< BasicJsonType > &&  )
delete
template<typename BasicJsonType >
nlohmann::detail::lexer< BasicJsonType >::~lexer ( )
default

Member Function Documentation

template<typename BasicJsonType >
void nlohmann::detail::lexer< BasicJsonType >::add ( int  c)
inlineprivate

add a character to token_buffer

Definition at line 3752 of file json.hpp.

3753  {
3754  token_buffer.push_back(std::char_traits<char>::to_char_type(c));
3755  }
string_t token_buffer
buffer for variable-length tokens (numbers, strings)
Definition: json.hpp:3938
template<typename BasicJsonType >
std::char_traits<char>::int_type nlohmann::detail::lexer< BasicJsonType >::get ( )
inlineprivate

Definition at line 3688 of file json.hpp.

References JSON_LIKELY.

3689  {
3692 
3693  if (next_unget)
3694  {
3695  // just reset the next_unget variable and work with current
3696  next_unget = false;
3697  }
3698  else
3699  {
3700  current = ia->get_character();
3701  }
3702 
3703  if (JSON_LIKELY(current != std::char_traits<char>::eof()))
3704  {
3705  token_string.push_back(std::char_traits<char>::to_char_type(current));
3706  }
3707 
3708  if (current == '\n')
3709  {
3710  ++position.lines_read;
3712  }
3713 
3714  return current;
3715  }
detail::input_adapter_t ia
input adapter
Definition: json.hpp:3923
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:762
position_t position
the start position of the current token
Definition: json.hpp:3932
#define JSON_LIKELY(x)
Definition: json.hpp:193
std::char_traits< char >::int_type current
the current character
Definition: json.hpp:3926
bool next_unget
whether the next get() call should just return current
Definition: json.hpp:3929
std::size_t lines_read
the number of lines read
Definition: json.hpp:764
std::vector< char > token_string
raw input token string (for error messages)
Definition: json.hpp:3935
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:760
template<typename BasicJsonType >
int nlohmann::detail::lexer< BasicJsonType >::get_codepoint ( )
inlineprivate

get codepoint from 4 hex characters following \u

For input "\u c1 c2 c3 c4" the codepoint is: (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4 = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)

Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f' must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The conversion is done by subtracting the offset (0x30, 0x37, and 0x57) between the ASCII value of the character and the desired integer value.

Returns
codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or non-hex character)

Definition at line 2591 of file json.hpp.

2592  {
2593  // this function only makes sense after reading `\u`
2594  assert(current == 'u');
2595  int codepoint = 0;
2596 
2597  const auto factors = { 12, 8, 4, 0 };
2598  for (const auto factor : factors)
2599  {
2600  get();
2601 
2602  if (current >= '0' and current <= '9')
2603  {
2604  codepoint += ((current - 0x30) << factor);
2605  }
2606  else if (current >= 'A' and current <= 'F')
2607  {
2608  codepoint += ((current - 0x37) << factor);
2609  }
2610  else if (current >= 'a' and current <= 'f')
2611  {
2612  codepoint += ((current - 0x57) << factor);
2613  }
2614  else
2615  {
2616  return -1;
2617  }
2618  }
2619 
2620  assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
2621  return codepoint;
2622  }
std::char_traits< char >::int_type current
the current character
Definition: json.hpp:3926
template<typename BasicJsonType >
static char nlohmann::detail::lexer< BasicJsonType >::get_decimal_point ( )
inlinestaticprivatenoexcept

return the locale-dependent decimal point

Definition at line 2565 of file json.hpp.

2566  {
2567  const auto loc = localeconv();
2568  assert(loc != nullptr);
2569  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
2570  }
template<typename BasicJsonType >
constexpr const char* nlohmann::detail::lexer< BasicJsonType >::get_error_message ( ) const
inlinenoexcept

return syntax error message

Definition at line 3823 of file json.hpp.

3824  {
3825  return error_message;
3826  }
const char * error_message
a description of occurred lexer errors
Definition: json.hpp:3941
template<typename BasicJsonType >
constexpr number_float_t nlohmann::detail::lexer< BasicJsonType >::get_number_float ( ) const
inlinenoexcept

return floating-point value

Definition at line 3775 of file json.hpp.

3776  {
3777  return value_float;
3778  }
number_float_t value_float
Definition: json.hpp:3946
template<typename BasicJsonType >
constexpr number_integer_t nlohmann::detail::lexer< BasicJsonType >::get_number_integer ( ) const
inlinenoexcept

return integer value

Definition at line 3763 of file json.hpp.

3764  {
3765  return value_integer;
3766  }
number_integer_t value_integer
Definition: json.hpp:3944
template<typename BasicJsonType >
constexpr number_unsigned_t nlohmann::detail::lexer< BasicJsonType >::get_number_unsigned ( ) const
inlinenoexcept

return unsigned integer value

Definition at line 3769 of file json.hpp.

3770  {
3771  return value_unsigned;
3772  }
number_unsigned_t value_unsigned
Definition: json.hpp:3945
template<typename BasicJsonType >
constexpr position_t nlohmann::detail::lexer< BasicJsonType >::get_position ( ) const
inlinenoexcept

return position of last read token

Definition at line 3791 of file json.hpp.

3792  {
3793  return position;
3794  }
position_t position
the start position of the current token
Definition: json.hpp:3932
template<typename BasicJsonType >
string_t& nlohmann::detail::lexer< BasicJsonType >::get_string ( )
inline

return current string value (implicitly resets the token; useful only once)

Definition at line 3781 of file json.hpp.

3782  {
3783  return token_buffer;
3784  }
string_t token_buffer
buffer for variable-length tokens (numbers, strings)
Definition: json.hpp:3938
template<typename BasicJsonType >
std::string nlohmann::detail::lexer< BasicJsonType >::get_token_string ( ) const
inline

return the last read token (for errors only). Will never contain EOF (an arbitrary value that is not a valid char value, often -1), because 255 may legitimately occur. May contain NUL, which should be escaped.

Definition at line 3799 of file json.hpp.

References cl_cmbl_bm::c, and nlohmann::detail::string.

3800  {
3801  // escape control characters
3802  std::string result;
3803  for (const auto c : token_string)
3804  {
3805  if ('\x00' <= c and c <= '\x1F')
3806  {
3807  // escape control characters
3808  char cs[9];
3809  snprintf(cs, 9, "<U+%.4X>", static_cast<unsigned char>(c));
3810  result += cs;
3811  }
3812  else
3813  {
3814  // add character as is
3815  result.push_back(c);
3816  }
3817  }
3818 
3819  return result;
3820  }
std::vector< char > token_string
raw input token string (for error messages)
Definition: json.hpp:3935
template<typename BasicJsonType >
bool nlohmann::detail::lexer< BasicJsonType >::next_byte_in_range ( std::initializer_list< int >  ranges)
inlineprivate

check if the next byte(s) are inside a given range

Adds the current byte and, for each passed range, reads a new byte and checks if it is inside the range. If a violation was detected, set up an error message and return false. Otherwise, return true.

Parameters
[in]rangeslist of integers; interpreted as list of pairs of inclusive lower and upper bound, respectively
Precondition
The passed list ranges must have 2, 4, or 6 elements; that is, 1, 2, or 3 pairs. This precondition is enforced by an assertion.
Returns
true if and only if no range violation was detected

Definition at line 2639 of file json.hpp.

References JSON_LIKELY, and Catch::Generators::range().

2640  {
2641  assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
2642  add(current);
2643 
2644  for (auto range = ranges.begin(); range != ranges.end(); ++range)
2645  {
2646  get();
2647  if (JSON_LIKELY(*range <= current and current <= *(++range)))
2648  {
2649  add(current);
2650  }
2651  else
2652  {
2653  error_message = "invalid string: ill-formed UTF-8 byte";
2654  return false;
2655  }
2656  }
2657 
2658  return true;
2659  }
void add(int c)
add a character to token_buffer
Definition: json.hpp:3752
#define JSON_LIKELY(x)
Definition: json.hpp:193
const char * error_message
a description of occurred lexer errors
Definition: json.hpp:3941
std::char_traits< char >::int_type current
the current character
Definition: json.hpp:3926
auto range(T const &first, T const &last) -> Generator< T >
Definition: catch.hpp:3156
template<typename BasicJsonType >
lexer& nlohmann::detail::lexer< BasicJsonType >::operator= ( lexer< BasicJsonType > &  )
delete
template<typename BasicJsonType >
lexer& nlohmann::detail::lexer< BasicJsonType >::operator= ( lexer< BasicJsonType > &&  )
delete
template<typename BasicJsonType >
void nlohmann::detail::lexer< BasicJsonType >::reset ( )
inlineprivatenoexcept

reset token_buffer; current character is beginning of token

Definition at line 3671 of file json.hpp.

3672  {
3673  token_buffer.clear();
3674  token_string.clear();
3675  token_string.push_back(std::char_traits<char>::to_char_type(current));
3676  }
string_t token_buffer
buffer for variable-length tokens (numbers, strings)
Definition: json.hpp:3938
std::char_traits< char >::int_type current
the current character
Definition: json.hpp:3926
std::vector< char > token_string
raw input token string (for error messages)
Definition: json.hpp:3935
template<typename BasicJsonType >
token_type nlohmann::detail::lexer< BasicJsonType >::scan ( )
inline

Definition at line 3850 of file json.hpp.

3851  {
3852  // initially, skip the BOM
3853  if (position.chars_read_total == 0 and not skip_bom())
3854  {
3855  error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
3856  return token_type::parse_error;
3857  }
3858 
3859  // read next character and ignore whitespace
3860  do
3861  {
3862  get();
3863  }
3864  while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
3865 
3866  switch (current)
3867  {
3868  // structural characters
3869  case '[':
3870  return token_type::begin_array;
3871  case ']':
3872  return token_type::end_array;
3873  case '{':
3874  return token_type::begin_object;
3875  case '}':
3876  return token_type::end_object;
3877  case ':':
3879  case ',':
3881 
3882  // literals
3883  case 't':
3884  return scan_literal("true", 4, token_type::literal_true);
3885  case 'f':
3886  return scan_literal("false", 5, token_type::literal_false);
3887  case 'n':
3888  return scan_literal("null", 4, token_type::literal_null);
3889 
3890  // string
3891  case '\"':
3892  return scan_string();
3893 
3894  // number
3895  case '-':
3896  case '0':
3897  case '1':
3898  case '2':
3899  case '3':
3900  case '4':
3901  case '5':
3902  case '6':
3903  case '7':
3904  case '8':
3905  case '9':
3906  return scan_number();
3907 
3908  // end of input (the null byte is needed when parsing from
3909  // string literals)
3910  case '\0':
3911  case std::char_traits<char>::eof():
3912  return token_type::end_of_input;
3913 
3914  // error
3915  default:
3916  error_message = "invalid literal";
3917  return token_type::parse_error;
3918  }
3919  }
token_type
token types for the parser
Definition: json.hpp:2484
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:3836
the character for object begin {
position_t position
the start position of the current token
Definition: json.hpp:3932
const char * error_message
a description of occurred lexer errors
Definition: json.hpp:3941
std::char_traits< char >::int_type current
the current character
Definition: json.hpp:3926
the character for array begin [
token_type scan_literal(const char *literal_text, const std::size_t length, token_type return_type)
Definition: json.hpp:3651
token_type scan_number()
scan a number literal
Definition: json.hpp:3317
token_type scan_string()
scan a string literal
Definition: json.hpp:2676
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:760
template<typename BasicJsonType >
token_type nlohmann::detail::lexer< BasicJsonType >::scan_literal ( const char *  literal_text,
const std::size_t  length,
token_type  return_type 
)
inlineprivate
Parameters
[in]literal_textthe literal text to expect
[in]lengththe length of the passed literal text
[in]return_typethe token type to return on success

Definition at line 3651 of file json.hpp.

References JSON_UNLIKELY.

3653  {
3654  assert(current == literal_text[0]);
3655  for (std::size_t i = 1; i < length; ++i)
3656  {
3657  if (JSON_UNLIKELY(get() != literal_text[i]))
3658  {
3659  error_message = "invalid literal";
3660  return token_type::parse_error;
3661  }
3662  }
3663  return return_type;
3664  }
#define JSON_UNLIKELY(x)
Definition: json.hpp:194
const char * error_message
a description of occurred lexer errors
Definition: json.hpp:3941
std::char_traits< char >::int_type current
the current character
Definition: json.hpp:3926
template<typename BasicJsonType >
token_type nlohmann::detail::lexer< BasicJsonType >::scan_number ( )
inlineprivate

scan a number literal

This function scans a string according to Sect. 6 of RFC 7159.

The function is realized with a deterministic finite state machine derived from the grammar described in RFC 7159. Starting in state "init", the input is read and used to determined the next state. Only state "done" accepts the number. State "error" is a trap state to model errors. In the table below, "anything" means any character but the ones listed before.

state 0 1-9 e E + - . anything
init zero any1 [error] [error] minus [error] [error]
minus zero any1 [error] [error] [error] [error] [error]
zero done done exponent done done decimal1 done
any1 any1 any1 exponent done done decimal1 done
decimal1 decimal2 [error] [error] [error] [error] [error] [error]
decimal2 decimal2 decimal2 exponent done done done done
exponent any2 any2 [error] sign sign [error] [error]
sign any2 any2 [error] [error] [error] [error] [error]
any2 any2 any2 done done done done done

The state machine is realized with one label per state (prefixed with "scan_number_") and goto statements between them. The state machine contains cycles, but any cycle can be left when EOF is read. Therefore, the function is guaranteed to terminate.

During scanning, the read bytes are stored in token_buffer. This string is then converted to a signed integer, an unsigned integer, or a floating-point number.

Returns
token_type::value_unsigned, token_type::value_integer, or token_type::value_float if number could be successfully scanned, token_type::parse_error otherwise
Note
The scanner is independent of the current locale. Internally, the locale's decimal point is used instead of . to work with the locale-dependent converters.

Definition at line 3317 of file json.hpp.

References x.

3318  {
3319  // reset token_buffer to store the number's bytes
3320  reset();
3321 
3322  // the type of the parsed number; initially set to unsigned; will be
3323  // changed if minus sign, decimal point or exponent is read
3324  token_type number_type = token_type::value_unsigned;
3325 
3326  // state (init): we just found out we need to scan a number
3327  switch (current)
3328  {
3329  case '-':
3330  {
3331  add(current);
3332  goto scan_number_minus;
3333  }
3334 
3335  case '0':
3336  {
3337  add(current);
3338  goto scan_number_zero;
3339  }
3340 
3341  case '1':
3342  case '2':
3343  case '3':
3344  case '4':
3345  case '5':
3346  case '6':
3347  case '7':
3348  case '8':
3349  case '9':
3350  {
3351  add(current);
3352  goto scan_number_any1;
3353  }
3354 
3355  // LCOV_EXCL_START
3356  default:
3357  {
3358  // all other characters are rejected outside scan_number()
3359  assert(false);
3360  }
3361  // LCOV_EXCL_STOP
3362  }
3363 
3364 scan_number_minus:
3365  // state: we just parsed a leading minus sign
3366  number_type = token_type::value_integer;
3367  switch (get())
3368  {
3369  case '0':
3370  {
3371  add(current);
3372  goto scan_number_zero;
3373  }
3374 
3375  case '1':
3376  case '2':
3377  case '3':
3378  case '4':
3379  case '5':
3380  case '6':
3381  case '7':
3382  case '8':
3383  case '9':
3384  {
3385  add(current);
3386  goto scan_number_any1;
3387  }
3388 
3389  default:
3390  {
3391  error_message = "invalid number; expected digit after '-'";
3392  return token_type::parse_error;
3393  }
3394  }
3395 
3396 scan_number_zero:
3397  // state: we just parse a zero (maybe with a leading minus sign)
3398  switch (get())
3399  {
3400  case '.':
3401  {
3403  goto scan_number_decimal1;
3404  }
3405 
3406  case 'e':
3407  case 'E':
3408  {
3409  add(current);
3410  goto scan_number_exponent;
3411  }
3412 
3413  default:
3414  goto scan_number_done;
3415  }
3416 
3417 scan_number_any1:
3418  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
3419  switch (get())
3420  {
3421  case '0':
3422  case '1':
3423  case '2':
3424  case '3':
3425  case '4':
3426  case '5':
3427  case '6':
3428  case '7':
3429  case '8':
3430  case '9':
3431  {
3432  add(current);
3433  goto scan_number_any1;
3434  }
3435 
3436  case '.':
3437  {
3439  goto scan_number_decimal1;
3440  }
3441 
3442  case 'e':
3443  case 'E':
3444  {
3445  add(current);
3446  goto scan_number_exponent;
3447  }
3448 
3449  default:
3450  goto scan_number_done;
3451  }
3452 
3453 scan_number_decimal1:
3454  // state: we just parsed a decimal point
3455  number_type = token_type::value_float;
3456  switch (get())
3457  {
3458  case '0':
3459  case '1':
3460  case '2':
3461  case '3':
3462  case '4':
3463  case '5':
3464  case '6':
3465  case '7':
3466  case '8':
3467  case '9':
3468  {
3469  add(current);
3470  goto scan_number_decimal2;
3471  }
3472 
3473  default:
3474  {
3475  error_message = "invalid number; expected digit after '.'";
3476  return token_type::parse_error;
3477  }
3478  }
3479 
3480 scan_number_decimal2:
3481  // we just parsed at least one number after a decimal point
3482  switch (get())
3483  {
3484  case '0':
3485  case '1':
3486  case '2':
3487  case '3':
3488  case '4':
3489  case '5':
3490  case '6':
3491  case '7':
3492  case '8':
3493  case '9':
3494  {
3495  add(current);
3496  goto scan_number_decimal2;
3497  }
3498 
3499  case 'e':
3500  case 'E':
3501  {
3502  add(current);
3503  goto scan_number_exponent;
3504  }
3505 
3506  default:
3507  goto scan_number_done;
3508  }
3509 
3510 scan_number_exponent:
3511  // we just parsed an exponent
3512  number_type = token_type::value_float;
3513  switch (get())
3514  {
3515  case '+':
3516  case '-':
3517  {
3518  add(current);
3519  goto scan_number_sign;
3520  }
3521 
3522  case '0':
3523  case '1':
3524  case '2':
3525  case '3':
3526  case '4':
3527  case '5':
3528  case '6':
3529  case '7':
3530  case '8':
3531  case '9':
3532  {
3533  add(current);
3534  goto scan_number_any2;
3535  }
3536 
3537  default:
3538  {
3539  error_message =
3540  "invalid number; expected '+', '-', or digit after exponent";
3541  return token_type::parse_error;
3542  }
3543  }
3544 
3545 scan_number_sign:
3546  // we just parsed an exponent sign
3547  switch (get())
3548  {
3549  case '0':
3550  case '1':
3551  case '2':
3552  case '3':
3553  case '4':
3554  case '5':
3555  case '6':
3556  case '7':
3557  case '8':
3558  case '9':
3559  {
3560  add(current);
3561  goto scan_number_any2;
3562  }
3563 
3564  default:
3565  {
3566  error_message = "invalid number; expected digit after exponent sign";
3567  return token_type::parse_error;
3568  }
3569  }
3570 
3571 scan_number_any2:
3572  // we just parsed a number after the exponent or exponent sign
3573  switch (get())
3574  {
3575  case '0':
3576  case '1':
3577  case '2':
3578  case '3':
3579  case '4':
3580  case '5':
3581  case '6':
3582  case '7':
3583  case '8':
3584  case '9':
3585  {
3586  add(current);
3587  goto scan_number_any2;
3588  }
3589 
3590  default:
3591  goto scan_number_done;
3592  }
3593 
3594 scan_number_done:
3595  // unget the character after the number (we only read it to know that
3596  // we are done scanning a number)
3597  unget();
3598 
3599  char* endptr = nullptr;
3600  errno = 0;
3601 
3602  // try to parse integers first and fall back to floats
3603  if (number_type == token_type::value_unsigned)
3604  {
3605  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
3606 
3607  // we checked the number format before
3608  assert(endptr == token_buffer.data() + token_buffer.size());
3609 
3610  if (errno == 0)
3611  {
3612  value_unsigned = static_cast<number_unsigned_t>(x);
3613  if (value_unsigned == x)
3614  {
3616  }
3617  }
3618  }
3619  else if (number_type == token_type::value_integer)
3620  {
3621  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
3622 
3623  // we checked the number format before
3624  assert(endptr == token_buffer.data() + token_buffer.size());
3625 
3626  if (errno == 0)
3627  {
3628  value_integer = static_cast<number_integer_t>(x);
3629  if (value_integer == x)
3630  {
3632  }
3633  }
3634  }
3635 
3636  // this code is reached if we parse a floating-point number or if an
3637  // integer conversion above failed
3638  strtof(value_float, token_buffer.data(), &endptr);
3639 
3640  // we checked the number format before
3641  assert(endptr == token_buffer.data() + token_buffer.size());
3642 
3643  return token_type::value_float;
3644  }
number_unsigned_t value_unsigned
Definition: json.hpp:3945
token_type
token types for the parser
Definition: json.hpp:2484
a signed integer – use get_number_integer() for actual value
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:2478
number_integer_t value_integer
Definition: json.hpp:3944
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:2477
string_t token_buffer
buffer for variable-length tokens (numbers, strings)
Definition: json.hpp:3938
void unget()
unget current character (read it again on next get)
Definition: json.hpp:3725
void add(int c)
add a character to token_buffer
Definition: json.hpp:3752
an unsigned integer – use get_number_unsigned() for actual value
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition: json.hpp:3671
an floating point number – use get_number_float() for actual value
static CCL_BEGIN_DECLS double x[111][8]
static void strtof(float &f, const char *str, char **endptr) noexcept
Definition: json.hpp:3262
const char decimal_point_char
the decimal point
Definition: json.hpp:3949
const char * error_message
a description of occurred lexer errors
Definition: json.hpp:3941
std::char_traits< char >::int_type current
the current character
Definition: json.hpp:3926
number_float_t value_float
Definition: json.hpp:3946
template<typename BasicJsonType >
token_type nlohmann::detail::lexer< BasicJsonType >::scan_string ( )
inlineprivate

scan a string literal

This function scans a string according to Sect. 7 of RFC 7159. While scanning, bytes are escaped and copied into buffer token_buffer. Then the function returns successfully, token_buffer is not null-terminated (as it may contain \0 bytes), and token_buffer.size() is the number of bytes in the string.

Returns
token_type::value_string if string could be successfully scanned, token_type::parse_error otherwise
Note
In case of errors, variable error_message contains a textual description.

Definition at line 2676 of file json.hpp.

References JSON_LIKELY, and JSON_UNLIKELY.

2677  {
2678  // reset token_buffer (ignore opening quote)
2679  reset();
2680 
2681  // we entered the function by reading an open quote
2682  assert(current == '\"');
2683 
2684  while (true)
2685  {
2686  // get next character
2687  switch (get())
2688  {
2689  // end of file while parsing string
2690  case std::char_traits<char>::eof():
2691  {
2692  error_message = "invalid string: missing closing quote";
2693  return token_type::parse_error;
2694  }
2695 
2696  // closing quote
2697  case '\"':
2698  {
2699  return token_type::value_string;
2700  }
2701 
2702  // escapes
2703  case '\\':
2704  {
2705  switch (get())
2706  {
2707  // quotation mark
2708  case '\"':
2709  add('\"');
2710  break;
2711  // reverse solidus
2712  case '\\':
2713  add('\\');
2714  break;
2715  // solidus
2716  case '/':
2717  add('/');
2718  break;
2719  // backspace
2720  case 'b':
2721  add('\b');
2722  break;
2723  // form feed
2724  case 'f':
2725  add('\f');
2726  break;
2727  // line feed
2728  case 'n':
2729  add('\n');
2730  break;
2731  // carriage return
2732  case 'r':
2733  add('\r');
2734  break;
2735  // tab
2736  case 't':
2737  add('\t');
2738  break;
2739 
2740  // unicode escapes
2741  case 'u':
2742  {
2743  const int codepoint1 = get_codepoint();
2744  int codepoint = codepoint1; // start with codepoint1
2745 
2746  if (JSON_UNLIKELY(codepoint1 == -1))
2747  {
2748  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2749  return token_type::parse_error;
2750  }
2751 
2752  // check if code point is a high surrogate
2753  if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
2754  {
2755  // expect next \uxxxx entry
2756  if (JSON_LIKELY(get() == '\\' and get() == 'u'))
2757  {
2758  const int codepoint2 = get_codepoint();
2759 
2760  if (JSON_UNLIKELY(codepoint2 == -1))
2761  {
2762  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2763  return token_type::parse_error;
2764  }
2765 
2766  // check if codepoint2 is a low surrogate
2767  if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
2768  {
2769  // overwrite codepoint
2770  codepoint =
2771  // high surrogate occupies the most significant 22 bits
2772  (codepoint1 << 10)
2773  // low surrogate occupies the least significant 15 bits
2774  + codepoint2
2775  // there is still the 0xD800, 0xDC00 and 0x10000 noise
2776  // in the result so we have to subtract with:
2777  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
2778  - 0x35FDC00;
2779  }
2780  else
2781  {
2782  error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2783  return token_type::parse_error;
2784  }
2785  }
2786  else
2787  {
2788  error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2789  return token_type::parse_error;
2790  }
2791  }
2792  else
2793  {
2794  if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
2795  {
2796  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2797  return token_type::parse_error;
2798  }
2799  }
2800 
2801  // result of the above calculation yields a proper codepoint
2802  assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
2803 
2804  // translate codepoint into bytes
2805  if (codepoint < 0x80)
2806  {
2807  // 1-byte characters: 0xxxxxxx (ASCII)
2808  add(codepoint);
2809  }
2810  else if (codepoint <= 0x7FF)
2811  {
2812  // 2-byte characters: 110xxxxx 10xxxxxx
2813  add(0xC0 | (codepoint >> 6));
2814  add(0x80 | (codepoint & 0x3F));
2815  }
2816  else if (codepoint <= 0xFFFF)
2817  {
2818  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
2819  add(0xE0 | (codepoint >> 12));
2820  add(0x80 | ((codepoint >> 6) & 0x3F));
2821  add(0x80 | (codepoint & 0x3F));
2822  }
2823  else
2824  {
2825  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
2826  add(0xF0 | (codepoint >> 18));
2827  add(0x80 | ((codepoint >> 12) & 0x3F));
2828  add(0x80 | ((codepoint >> 6) & 0x3F));
2829  add(0x80 | (codepoint & 0x3F));
2830  }
2831 
2832  break;
2833  }
2834 
2835  // other characters after escape
2836  default:
2837  error_message = "invalid string: forbidden character after backslash";
2838  return token_type::parse_error;
2839  }
2840 
2841  break;
2842  }
2843 
2844  // invalid control characters
2845  case 0x00:
2846  {
2847  error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
2848  return token_type::parse_error;
2849  }
2850 
2851  case 0x01:
2852  {
2853  error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
2854  return token_type::parse_error;
2855  }
2856 
2857  case 0x02:
2858  {
2859  error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
2860  return token_type::parse_error;
2861  }
2862 
2863  case 0x03:
2864  {
2865  error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
2866  return token_type::parse_error;
2867  }
2868 
2869  case 0x04:
2870  {
2871  error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
2872  return token_type::parse_error;
2873  }
2874 
2875  case 0x05:
2876  {
2877  error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
2878  return token_type::parse_error;
2879  }
2880 
2881  case 0x06:
2882  {
2883  error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
2884  return token_type::parse_error;
2885  }
2886 
2887  case 0x07:
2888  {
2889  error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
2890  return token_type::parse_error;
2891  }
2892 
2893  case 0x08:
2894  {
2895  error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
2896  return token_type::parse_error;
2897  }
2898 
2899  case 0x09:
2900  {
2901  error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
2902  return token_type::parse_error;
2903  }
2904 
2905  case 0x0A:
2906  {
2907  error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
2908  return token_type::parse_error;
2909  }
2910 
2911  case 0x0B:
2912  {
2913  error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
2914  return token_type::parse_error;
2915  }
2916 
2917  case 0x0C:
2918  {
2919  error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
2920  return token_type::parse_error;
2921  }
2922 
2923  case 0x0D:
2924  {
2925  error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
2926  return token_type::parse_error;
2927  }
2928 
2929  case 0x0E:
2930  {
2931  error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
2932  return token_type::parse_error;
2933  }
2934 
2935  case 0x0F:
2936  {
2937  error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
2938  return token_type::parse_error;
2939  }
2940 
2941  case 0x10:
2942  {
2943  error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
2944  return token_type::parse_error;
2945  }
2946 
2947  case 0x11:
2948  {
2949  error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
2950  return token_type::parse_error;
2951  }
2952 
2953  case 0x12:
2954  {
2955  error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
2956  return token_type::parse_error;
2957  }
2958 
2959  case 0x13:
2960  {
2961  error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
2962  return token_type::parse_error;
2963  }
2964 
2965  case 0x14:
2966  {
2967  error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
2968  return token_type::parse_error;
2969  }
2970 
2971  case 0x15:
2972  {
2973  error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
2974  return token_type::parse_error;
2975  }
2976 
2977  case 0x16:
2978  {
2979  error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
2980  return token_type::parse_error;
2981  }
2982 
2983  case 0x17:
2984  {
2985  error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
2986  return token_type::parse_error;
2987  }
2988 
2989  case 0x18:
2990  {
2991  error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
2992  return token_type::parse_error;
2993  }
2994 
2995  case 0x19:
2996  {
2997  error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
2998  return token_type::parse_error;
2999  }
3000 
3001  case 0x1A:
3002  {
3003  error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
3004  return token_type::parse_error;
3005  }
3006 
3007  case 0x1B:
3008  {
3009  error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
3010  return token_type::parse_error;
3011  }
3012 
3013  case 0x1C:
3014  {
3015  error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
3016  return token_type::parse_error;
3017  }
3018 
3019  case 0x1D:
3020  {
3021  error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
3022  return token_type::parse_error;
3023  }
3024 
3025  case 0x1E:
3026  {
3027  error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
3028  return token_type::parse_error;
3029  }
3030 
3031  case 0x1F:
3032  {
3033  error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
3034  return token_type::parse_error;
3035  }
3036 
3037  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
3038  case 0x20:
3039  case 0x21:
3040  case 0x23:
3041  case 0x24:
3042  case 0x25:
3043  case 0x26:
3044  case 0x27:
3045  case 0x28:
3046  case 0x29:
3047  case 0x2A:
3048  case 0x2B:
3049  case 0x2C:
3050  case 0x2D:
3051  case 0x2E:
3052  case 0x2F:
3053  case 0x30:
3054  case 0x31:
3055  case 0x32:
3056  case 0x33:
3057  case 0x34:
3058  case 0x35:
3059  case 0x36:
3060  case 0x37:
3061  case 0x38:
3062  case 0x39:
3063  case 0x3A:
3064  case 0x3B:
3065  case 0x3C:
3066  case 0x3D:
3067  case 0x3E:
3068  case 0x3F:
3069  case 0x40:
3070  case 0x41:
3071  case 0x42:
3072  case 0x43:
3073  case 0x44:
3074  case 0x45:
3075  case 0x46:
3076  case 0x47:
3077  case 0x48:
3078  case 0x49:
3079  case 0x4A:
3080  case 0x4B:
3081  case 0x4C:
3082  case 0x4D:
3083  case 0x4E:
3084  case 0x4F:
3085  case 0x50:
3086  case 0x51:
3087  case 0x52:
3088  case 0x53:
3089  case 0x54:
3090  case 0x55:
3091  case 0x56:
3092  case 0x57:
3093  case 0x58:
3094  case 0x59:
3095  case 0x5A:
3096  case 0x5B:
3097  case 0x5D:
3098  case 0x5E:
3099  case 0x5F:
3100  case 0x60:
3101  case 0x61:
3102  case 0x62:
3103  case 0x63:
3104  case 0x64:
3105  case 0x65:
3106  case 0x66:
3107  case 0x67:
3108  case 0x68:
3109  case 0x69:
3110  case 0x6A:
3111  case 0x6B:
3112  case 0x6C:
3113  case 0x6D:
3114  case 0x6E:
3115  case 0x6F:
3116  case 0x70:
3117  case 0x71:
3118  case 0x72:
3119  case 0x73:
3120  case 0x74:
3121  case 0x75:
3122  case 0x76:
3123  case 0x77:
3124  case 0x78:
3125  case 0x79:
3126  case 0x7A:
3127  case 0x7B:
3128  case 0x7C:
3129  case 0x7D:
3130  case 0x7E:
3131  case 0x7F:
3132  {
3133  add(current);
3134  break;
3135  }
3136 
3137  // U+0080..U+07FF: bytes C2..DF 80..BF
3138  case 0xC2:
3139  case 0xC3:
3140  case 0xC4:
3141  case 0xC5:
3142  case 0xC6:
3143  case 0xC7:
3144  case 0xC8:
3145  case 0xC9:
3146  case 0xCA:
3147  case 0xCB:
3148  case 0xCC:
3149  case 0xCD:
3150  case 0xCE:
3151  case 0xCF:
3152  case 0xD0:
3153  case 0xD1:
3154  case 0xD2:
3155  case 0xD3:
3156  case 0xD4:
3157  case 0xD5:
3158  case 0xD6:
3159  case 0xD7:
3160  case 0xD8:
3161  case 0xD9:
3162  case 0xDA:
3163  case 0xDB:
3164  case 0xDC:
3165  case 0xDD:
3166  case 0xDE:
3167  case 0xDF:
3168  {
3169  if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
3170  {
3171  return token_type::parse_error;
3172  }
3173  break;
3174  }
3175 
3176  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
3177  case 0xE0:
3178  {
3179  if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
3180  {
3181  return token_type::parse_error;
3182  }
3183  break;
3184  }
3185 
3186  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
3187  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
3188  case 0xE1:
3189  case 0xE2:
3190  case 0xE3:
3191  case 0xE4:
3192  case 0xE5:
3193  case 0xE6:
3194  case 0xE7:
3195  case 0xE8:
3196  case 0xE9:
3197  case 0xEA:
3198  case 0xEB:
3199  case 0xEC:
3200  case 0xEE:
3201  case 0xEF:
3202  {
3203  if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
3204  {
3205  return token_type::parse_error;
3206  }
3207  break;
3208  }
3209 
3210  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
3211  case 0xED:
3212  {
3213  if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
3214  {
3215  return token_type::parse_error;
3216  }
3217  break;
3218  }
3219 
3220  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
3221  case 0xF0:
3222  {
3223  if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
3224  {
3225  return token_type::parse_error;
3226  }
3227  break;
3228  }
3229 
3230  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
3231  case 0xF1:
3232  case 0xF2:
3233  case 0xF3:
3234  {
3235  if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
3236  {
3237  return token_type::parse_error;
3238  }
3239  break;
3240  }
3241 
3242  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
3243  case 0xF4:
3244  {
3245  if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
3246  {
3247  return token_type::parse_error;
3248  }
3249  break;
3250  }
3251 
3252  // remaining bytes (80..C1 and F5..FF) are ill-formed
3253  default:
3254  {
3255  error_message = "invalid string: ill-formed UTF-8 byte";
3256  return token_type::parse_error;
3257  }
3258  }
3259  }
3260  }
#define JSON_UNLIKELY(x)
Definition: json.hpp:194
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition: json.hpp:3671
#define JSON_LIKELY(x)
Definition: json.hpp:193
std::char_traits< char >::int_type current
the current character
Definition: json.hpp:3926
template<typename BasicJsonType >
bool nlohmann::detail::lexer< BasicJsonType >::skip_bom ( )
inline

skip the UTF-8 byte order mark

Returns
true iff there is no BOM or the correct BOM has been skipped

Definition at line 3836 of file json.hpp.

3837  {
3838  if (get() == 0xEF)
3839  {
3840  // check if we completely parse the BOM
3841  return get() == 0xBB and get() == 0xBF;
3842  }
3843 
3844  // the first character is not the beginning of the BOM; unget it to
3845  // process is later
3846  unget();
3847  return true;
3848  }
void unget()
unget current character (read it again on next get)
Definition: json.hpp:3725
template<typename BasicJsonType >
static void nlohmann::detail::lexer< BasicJsonType >::strtof ( float &  f,
const char *  str,
char **  endptr 
)
inlinestaticprivatenoexcept

Definition at line 3262 of file json.hpp.

3263  {
3264  f = std::strtof(str, endptr);
3265  }
template<typename BasicJsonType >
static void nlohmann::detail::lexer< BasicJsonType >::strtof ( double f,
const char *  str,
char **  endptr 
)
inlinestaticprivatenoexcept

Definition at line 3267 of file json.hpp.

3268  {
3269  f = std::strtod(str, endptr);
3270  }
template<typename BasicJsonType >
static void nlohmann::detail::lexer< BasicJsonType >::strtof ( long double f,
const char *  str,
char **  endptr 
)
inlinestaticprivatenoexcept

Definition at line 3272 of file json.hpp.

3273  {
3274  f = std::strtold(str, endptr);
3275  }
template<typename BasicJsonType >
static const char* nlohmann::detail::lexer< BasicJsonType >::token_type_name ( const token_type  t)
inlinestaticnoexcept

return name of values of type token_type (only used for errors)

Definition at line 2506 of file json.hpp.

References nlohmann::detail::lexer< BasicJsonType >::value_float, nlohmann::detail::lexer< BasicJsonType >::value_integer, and nlohmann::detail::lexer< BasicJsonType >::value_unsigned.

2507  {
2508  switch (t)
2509  {
2511  return "<uninitialized>";
2513  return "true literal";
2515  return "false literal";
2517  return "null literal";
2519  return "string literal";
2523  return "number literal";
2525  return "'['";
2527  return "'{'";
2528  case token_type::end_array:
2529  return "']'";
2531  return "'}'";
2533  return "':'";
2535  return "','";
2537  return "<parse error>";
2539  return "end of input";
2541  return "'[', '{', or a literal";
2542  // LCOV_EXCL_START
2543  default: // catch non-enum values
2544  return "unknown token";
2545  // LCOV_EXCL_STOP
2546  }
2547  }
a signed integer – use get_number_integer() for actual value
a string – use get_string() for actual value
the character for object begin {
an unsigned integer – use get_number_unsigned() for actual value
an floating point number – use get_number_float() for actual value
the character for array begin [
a literal or the begin of a value (only for diagnostics)
indicating the scanner is uninitialized
indicating the end of the input buffer
template<typename BasicJsonType >
void nlohmann::detail::lexer< BasicJsonType >::unget ( )
inlineprivate

unget current character (read it again on next get)

We implement unget by setting variable next_unget to true. The input is not changed - we just simulate ungetting by modifying chars_read_total, chars_read_current_line, and token_string. The next call to get() will behave as if the unget character is read again.

Definition at line 3725 of file json.hpp.

References JSON_LIKELY.

3726  {
3727  next_unget = true;
3728 
3730 
3731  // in case we "unget" a newline, we have to also decrement the lines_read
3733  {
3734  if (position.lines_read > 0)
3735  {
3736  --position.lines_read;
3737  }
3738  }
3739  else
3740  {
3742  }
3743 
3744  if (JSON_LIKELY(current != std::char_traits<char>::eof()))
3745  {
3746  assert(token_string.size() != 0);
3747  token_string.pop_back();
3748  }
3749  }
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:762
position_t position
the start position of the current token
Definition: json.hpp:3932
#define JSON_LIKELY(x)
Definition: json.hpp:193
std::char_traits< char >::int_type current
the current character
Definition: json.hpp:3926
bool next_unget
whether the next get() call should just return current
Definition: json.hpp:3929
std::size_t lines_read
the number of lines read
Definition: json.hpp:764
std::vector< char > token_string
raw input token string (for error messages)
Definition: json.hpp:3935
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:760

Member Data Documentation

template<typename BasicJsonType >
std::char_traits<char>::int_type nlohmann::detail::lexer< BasicJsonType >::current = std::char_traits<char>::eof()
private

the current character

Definition at line 3926 of file json.hpp.

template<typename BasicJsonType >
const char nlohmann::detail::lexer< BasicJsonType >::decimal_point_char = '.'
private

the decimal point

Definition at line 3949 of file json.hpp.

template<typename BasicJsonType >
const char* nlohmann::detail::lexer< BasicJsonType >::error_message = ""
private

a description of occurred lexer errors

Definition at line 3941 of file json.hpp.

template<typename BasicJsonType >
detail::input_adapter_t nlohmann::detail::lexer< BasicJsonType >::ia = nullptr
private

input adapter

Definition at line 3923 of file json.hpp.

template<typename BasicJsonType >
bool nlohmann::detail::lexer< BasicJsonType >::next_unget = false
private

whether the next get() call should just return current

Definition at line 3929 of file json.hpp.

template<typename BasicJsonType >
position_t nlohmann::detail::lexer< BasicJsonType >::position
private

the start position of the current token

Definition at line 3932 of file json.hpp.

template<typename BasicJsonType >
string_t nlohmann::detail::lexer< BasicJsonType >::token_buffer {}
private

buffer for variable-length tokens (numbers, strings)

Definition at line 3938 of file json.hpp.

template<typename BasicJsonType >
std::vector<char> nlohmann::detail::lexer< BasicJsonType >::token_string {}
private

raw input token string (for error messages)

Definition at line 3935 of file json.hpp.

template<typename BasicJsonType >
number_float_t nlohmann::detail::lexer< BasicJsonType >::value_float = 0
private

Definition at line 3946 of file json.hpp.

template<typename BasicJsonType >
number_integer_t nlohmann::detail::lexer< BasicJsonType >::value_integer = 0
private

Definition at line 3944 of file json.hpp.

template<typename BasicJsonType >
number_unsigned_t nlohmann::detail::lexer< BasicJsonType >::value_unsigned = 0
private

Definition at line 3945 of file json.hpp.


The documentation for this class was generated from the following file: