99.22% Lines (1268/1278) 100.00% Functions (30/30)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3   // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com) 3   // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
4   // 4   //
5   // Distributed under the Boost Software License, Version 1.0. (See accompanying 5   // Distributed under the Boost Software License, Version 1.0. (See accompanying
6   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7   // 7   //
8   // Official repository: https://github.com/boostorg/json 8   // Official repository: https://github.com/boostorg/json
9   // 9   //
10   10  
11   #ifndef BOOST_JSON_BASIC_PARSER_IMPL_HPP 11   #ifndef BOOST_JSON_BASIC_PARSER_IMPL_HPP
12   #define BOOST_JSON_BASIC_PARSER_IMPL_HPP 12   #define BOOST_JSON_BASIC_PARSER_IMPL_HPP
13   13  
14   #include <boost/json/detail/config.hpp> 14   #include <boost/json/detail/config.hpp>
15   #include <boost/json/detail/literals.hpp> 15   #include <boost/json/detail/literals.hpp>
16   #include <boost/json/basic_parser.hpp> 16   #include <boost/json/basic_parser.hpp>
17   #include <boost/json/error.hpp> 17   #include <boost/json/error.hpp>
18   #include <boost/json/detail/buffer.hpp> 18   #include <boost/json/detail/buffer.hpp>
19   #include <boost/json/detail/charconv/from_chars.hpp> 19   #include <boost/json/detail/charconv/from_chars.hpp>
20   #include <boost/json/detail/sse2.hpp> 20   #include <boost/json/detail/sse2.hpp>
21   #include <boost/mp11/algorithm.hpp> 21   #include <boost/mp11/algorithm.hpp>
22   #include <boost/mp11/integral.hpp> 22   #include <boost/mp11/integral.hpp>
23   #include <cmath> 23   #include <cmath>
24   #include <limits> 24   #include <limits>
25   #include <cstring> 25   #include <cstring>
26   26  
27   #ifdef _MSC_VER 27   #ifdef _MSC_VER
28   #pragma warning(push) 28   #pragma warning(push)
29   #pragma warning(disable: 4702) // unreachable code 29   #pragma warning(disable: 4702) // unreachable code
30   #pragma warning(disable: 4127) // conditional expression is constant 30   #pragma warning(disable: 4127) // conditional expression is constant
31   #endif 31   #endif
32   32  
33   /* This file must be manually included to get the 33   /* This file must be manually included to get the
34   function template definitions for basic_parser. 34   function template definitions for basic_parser.
35   */ 35   */
36   36  
37   /* Reference: 37   /* Reference:
38   38  
39   https://www.json.org/ 39   https://www.json.org/
40   40  
41   RFC 7159: The JavaScript Object Notation (JSON) Data Interchange Format 41   RFC 7159: The JavaScript Object Notation (JSON) Data Interchange Format
42   https://tools.ietf.org/html/rfc7159 42   https://tools.ietf.org/html/rfc7159
43   43  
44   https://ampl.com/netlib/fp/dtoa.c 44   https://ampl.com/netlib/fp/dtoa.c
45   */ 45   */
46   46  
47   #ifndef BOOST_JSON_DOCS 47   #ifndef BOOST_JSON_DOCS
48   48  
49   namespace boost { 49   namespace boost {
50   namespace json { 50   namespace json {
51   namespace detail { 51   namespace detail {
52   52  
53   inline 53   inline
54   double 54   double
HITCBC 55   1035607 pow10(int exp) noexcept 55   1035607 pow10(int exp) noexcept
56   { 56   {
57   static double const tab[618] = { 57   static double const tab[618] = {
58   1e-308, 1e-307, 1e-306, 1e-305, 1e-304, 1e-303, 1e-302, 1e-301, 58   1e-308, 1e-307, 1e-306, 1e-305, 1e-304, 1e-303, 1e-302, 1e-301,
59   59  
60   1e-300, 1e-299, 1e-298, 1e-297, 1e-296, 1e-295, 1e-294, 1e-293, 1e-292, 1e-291, 60   1e-300, 1e-299, 1e-298, 1e-297, 1e-296, 1e-295, 1e-294, 1e-293, 1e-292, 1e-291,
61   1e-290, 1e-289, 1e-288, 1e-287, 1e-286, 1e-285, 1e-284, 1e-283, 1e-282, 1e-281, 61   1e-290, 1e-289, 1e-288, 1e-287, 1e-286, 1e-285, 1e-284, 1e-283, 1e-282, 1e-281,
62   1e-280, 1e-279, 1e-278, 1e-277, 1e-276, 1e-275, 1e-274, 1e-273, 1e-272, 1e-271, 62   1e-280, 1e-279, 1e-278, 1e-277, 1e-276, 1e-275, 1e-274, 1e-273, 1e-272, 1e-271,
63   1e-270, 1e-269, 1e-268, 1e-267, 1e-266, 1e-265, 1e-264, 1e-263, 1e-262, 1e-261, 63   1e-270, 1e-269, 1e-268, 1e-267, 1e-266, 1e-265, 1e-264, 1e-263, 1e-262, 1e-261,
64   1e-260, 1e-259, 1e-258, 1e-257, 1e-256, 1e-255, 1e-254, 1e-253, 1e-252, 1e-251, 64   1e-260, 1e-259, 1e-258, 1e-257, 1e-256, 1e-255, 1e-254, 1e-253, 1e-252, 1e-251,
65   1e-250, 1e-249, 1e-248, 1e-247, 1e-246, 1e-245, 1e-244, 1e-243, 1e-242, 1e-241, 65   1e-250, 1e-249, 1e-248, 1e-247, 1e-246, 1e-245, 1e-244, 1e-243, 1e-242, 1e-241,
66   1e-240, 1e-239, 1e-238, 1e-237, 1e-236, 1e-235, 1e-234, 1e-233, 1e-232, 1e-231, 66   1e-240, 1e-239, 1e-238, 1e-237, 1e-236, 1e-235, 1e-234, 1e-233, 1e-232, 1e-231,
67   1e-230, 1e-229, 1e-228, 1e-227, 1e-226, 1e-225, 1e-224, 1e-223, 1e-222, 1e-221, 67   1e-230, 1e-229, 1e-228, 1e-227, 1e-226, 1e-225, 1e-224, 1e-223, 1e-222, 1e-221,
68   1e-220, 1e-219, 1e-218, 1e-217, 1e-216, 1e-215, 1e-214, 1e-213, 1e-212, 1e-211, 68   1e-220, 1e-219, 1e-218, 1e-217, 1e-216, 1e-215, 1e-214, 1e-213, 1e-212, 1e-211,
69   1e-210, 1e-209, 1e-208, 1e-207, 1e-206, 1e-205, 1e-204, 1e-203, 1e-202, 1e-201, 69   1e-210, 1e-209, 1e-208, 1e-207, 1e-206, 1e-205, 1e-204, 1e-203, 1e-202, 1e-201,
70   70  
71   1e-200, 1e-199, 1e-198, 1e-197, 1e-196, 1e-195, 1e-194, 1e-193, 1e-192, 1e-191, 71   1e-200, 1e-199, 1e-198, 1e-197, 1e-196, 1e-195, 1e-194, 1e-193, 1e-192, 1e-191,
72   1e-190, 1e-189, 1e-188, 1e-187, 1e-186, 1e-185, 1e-184, 1e-183, 1e-182, 1e-181, 72   1e-190, 1e-189, 1e-188, 1e-187, 1e-186, 1e-185, 1e-184, 1e-183, 1e-182, 1e-181,
73   1e-180, 1e-179, 1e-178, 1e-177, 1e-176, 1e-175, 1e-174, 1e-173, 1e-172, 1e-171, 73   1e-180, 1e-179, 1e-178, 1e-177, 1e-176, 1e-175, 1e-174, 1e-173, 1e-172, 1e-171,
74   1e-170, 1e-169, 1e-168, 1e-167, 1e-166, 1e-165, 1e-164, 1e-163, 1e-162, 1e-161, 74   1e-170, 1e-169, 1e-168, 1e-167, 1e-166, 1e-165, 1e-164, 1e-163, 1e-162, 1e-161,
75   1e-160, 1e-159, 1e-158, 1e-157, 1e-156, 1e-155, 1e-154, 1e-153, 1e-152, 1e-151, 75   1e-160, 1e-159, 1e-158, 1e-157, 1e-156, 1e-155, 1e-154, 1e-153, 1e-152, 1e-151,
76   1e-150, 1e-149, 1e-148, 1e-147, 1e-146, 1e-145, 1e-144, 1e-143, 1e-142, 1e-141, 76   1e-150, 1e-149, 1e-148, 1e-147, 1e-146, 1e-145, 1e-144, 1e-143, 1e-142, 1e-141,
77   1e-140, 1e-139, 1e-138, 1e-137, 1e-136, 1e-135, 1e-134, 1e-133, 1e-132, 1e-131, 77   1e-140, 1e-139, 1e-138, 1e-137, 1e-136, 1e-135, 1e-134, 1e-133, 1e-132, 1e-131,
78   1e-130, 1e-129, 1e-128, 1e-127, 1e-126, 1e-125, 1e-124, 1e-123, 1e-122, 1e-121, 78   1e-130, 1e-129, 1e-128, 1e-127, 1e-126, 1e-125, 1e-124, 1e-123, 1e-122, 1e-121,
79   1e-120, 1e-119, 1e-118, 1e-117, 1e-116, 1e-115, 1e-114, 1e-113, 1e-112, 1e-111, 79   1e-120, 1e-119, 1e-118, 1e-117, 1e-116, 1e-115, 1e-114, 1e-113, 1e-112, 1e-111,
80   1e-110, 1e-109, 1e-108, 1e-107, 1e-106, 1e-105, 1e-104, 1e-103, 1e-102, 1e-101, 80   1e-110, 1e-109, 1e-108, 1e-107, 1e-106, 1e-105, 1e-104, 1e-103, 1e-102, 1e-101,
81   81  
82   1e-100, 1e-099, 1e-098, 1e-097, 1e-096, 1e-095, 1e-094, 1e-093, 1e-092, 1e-091, 82   1e-100, 1e-099, 1e-098, 1e-097, 1e-096, 1e-095, 1e-094, 1e-093, 1e-092, 1e-091,
83   1e-090, 1e-089, 1e-088, 1e-087, 1e-086, 1e-085, 1e-084, 1e-083, 1e-082, 1e-081, 83   1e-090, 1e-089, 1e-088, 1e-087, 1e-086, 1e-085, 1e-084, 1e-083, 1e-082, 1e-081,
84   1e-080, 1e-079, 1e-078, 1e-077, 1e-076, 1e-075, 1e-074, 1e-073, 1e-072, 1e-071, 84   1e-080, 1e-079, 1e-078, 1e-077, 1e-076, 1e-075, 1e-074, 1e-073, 1e-072, 1e-071,
85   1e-070, 1e-069, 1e-068, 1e-067, 1e-066, 1e-065, 1e-064, 1e-063, 1e-062, 1e-061, 85   1e-070, 1e-069, 1e-068, 1e-067, 1e-066, 1e-065, 1e-064, 1e-063, 1e-062, 1e-061,
86   1e-060, 1e-059, 1e-058, 1e-057, 1e-056, 1e-055, 1e-054, 1e-053, 1e-052, 1e-051, 86   1e-060, 1e-059, 1e-058, 1e-057, 1e-056, 1e-055, 1e-054, 1e-053, 1e-052, 1e-051,
87   1e-050, 1e-049, 1e-048, 1e-047, 1e-046, 1e-045, 1e-044, 1e-043, 1e-042, 1e-041, 87   1e-050, 1e-049, 1e-048, 1e-047, 1e-046, 1e-045, 1e-044, 1e-043, 1e-042, 1e-041,
88   1e-040, 1e-039, 1e-038, 1e-037, 1e-036, 1e-035, 1e-034, 1e-033, 1e-032, 1e-031, 88   1e-040, 1e-039, 1e-038, 1e-037, 1e-036, 1e-035, 1e-034, 1e-033, 1e-032, 1e-031,
89   1e-030, 1e-029, 1e-028, 1e-027, 1e-026, 1e-025, 1e-024, 1e-023, 1e-022, 1e-021, 89   1e-030, 1e-029, 1e-028, 1e-027, 1e-026, 1e-025, 1e-024, 1e-023, 1e-022, 1e-021,
90   1e-020, 1e-019, 1e-018, 1e-017, 1e-016, 1e-015, 1e-014, 1e-013, 1e-012, 1e-011, 90   1e-020, 1e-019, 1e-018, 1e-017, 1e-016, 1e-015, 1e-014, 1e-013, 1e-012, 1e-011,
91   1e-010, 1e-009, 1e-008, 1e-007, 1e-006, 1e-005, 1e-004, 1e-003, 1e-002, 1e-001, 91   1e-010, 1e-009, 1e-008, 1e-007, 1e-006, 1e-005, 1e-004, 1e-003, 1e-002, 1e-001,
92   92  
93   1e+000, 1e+001, 1e+002, 1e+003, 1e+004, 1e+005, 1e+006, 1e+007, 1e+008, 1e+009, 93   1e+000, 1e+001, 1e+002, 1e+003, 1e+004, 1e+005, 1e+006, 1e+007, 1e+008, 1e+009,
94   1e+010, 1e+011, 1e+012, 1e+013, 1e+014, 1e+015, 1e+016, 1e+017, 1e+018, 1e+019, 94   1e+010, 1e+011, 1e+012, 1e+013, 1e+014, 1e+015, 1e+016, 1e+017, 1e+018, 1e+019,
95   1e+020, 1e+021, 1e+022, 1e+023, 1e+024, 1e+025, 1e+026, 1e+027, 1e+028, 1e+029, 95   1e+020, 1e+021, 1e+022, 1e+023, 1e+024, 1e+025, 1e+026, 1e+027, 1e+028, 1e+029,
96   1e+030, 1e+031, 1e+032, 1e+033, 1e+034, 1e+035, 1e+036, 1e+037, 1e+038, 1e+039, 96   1e+030, 1e+031, 1e+032, 1e+033, 1e+034, 1e+035, 1e+036, 1e+037, 1e+038, 1e+039,
97   1e+040, 1e+041, 1e+042, 1e+043, 1e+044, 1e+045, 1e+046, 1e+047, 1e+048, 1e+049, 97   1e+040, 1e+041, 1e+042, 1e+043, 1e+044, 1e+045, 1e+046, 1e+047, 1e+048, 1e+049,
98   1e+050, 1e+051, 1e+052, 1e+053, 1e+054, 1e+055, 1e+056, 1e+057, 1e+058, 1e+059, 98   1e+050, 1e+051, 1e+052, 1e+053, 1e+054, 1e+055, 1e+056, 1e+057, 1e+058, 1e+059,
99   1e+060, 1e+061, 1e+062, 1e+063, 1e+064, 1e+065, 1e+066, 1e+067, 1e+068, 1e+069, 99   1e+060, 1e+061, 1e+062, 1e+063, 1e+064, 1e+065, 1e+066, 1e+067, 1e+068, 1e+069,
100   1e+070, 1e+071, 1e+072, 1e+073, 1e+074, 1e+075, 1e+076, 1e+077, 1e+078, 1e+079, 100   1e+070, 1e+071, 1e+072, 1e+073, 1e+074, 1e+075, 1e+076, 1e+077, 1e+078, 1e+079,
101   1e+080, 1e+081, 1e+082, 1e+083, 1e+084, 1e+085, 1e+086, 1e+087, 1e+088, 1e+089, 101   1e+080, 1e+081, 1e+082, 1e+083, 1e+084, 1e+085, 1e+086, 1e+087, 1e+088, 1e+089,
102   1e+090, 1e+091, 1e+092, 1e+093, 1e+094, 1e+095, 1e+096, 1e+097, 1e+098, 1e+099, 102   1e+090, 1e+091, 1e+092, 1e+093, 1e+094, 1e+095, 1e+096, 1e+097, 1e+098, 1e+099,
103   103  
104   1e+100, 1e+101, 1e+102, 1e+103, 1e+104, 1e+105, 1e+106, 1e+107, 1e+108, 1e+109, 104   1e+100, 1e+101, 1e+102, 1e+103, 1e+104, 1e+105, 1e+106, 1e+107, 1e+108, 1e+109,
105   1e+110, 1e+111, 1e+112, 1e+113, 1e+114, 1e+115, 1e+116, 1e+117, 1e+118, 1e+119, 105   1e+110, 1e+111, 1e+112, 1e+113, 1e+114, 1e+115, 1e+116, 1e+117, 1e+118, 1e+119,
106   1e+120, 1e+121, 1e+122, 1e+123, 1e+124, 1e+125, 1e+126, 1e+127, 1e+128, 1e+129, 106   1e+120, 1e+121, 1e+122, 1e+123, 1e+124, 1e+125, 1e+126, 1e+127, 1e+128, 1e+129,
107   1e+130, 1e+131, 1e+132, 1e+133, 1e+134, 1e+135, 1e+136, 1e+137, 1e+138, 1e+139, 107   1e+130, 1e+131, 1e+132, 1e+133, 1e+134, 1e+135, 1e+136, 1e+137, 1e+138, 1e+139,
108   1e+140, 1e+141, 1e+142, 1e+143, 1e+144, 1e+145, 1e+146, 1e+147, 1e+148, 1e+149, 108   1e+140, 1e+141, 1e+142, 1e+143, 1e+144, 1e+145, 1e+146, 1e+147, 1e+148, 1e+149,
109   1e+150, 1e+151, 1e+152, 1e+153, 1e+154, 1e+155, 1e+156, 1e+157, 1e+158, 1e+159, 109   1e+150, 1e+151, 1e+152, 1e+153, 1e+154, 1e+155, 1e+156, 1e+157, 1e+158, 1e+159,
110   1e+160, 1e+161, 1e+162, 1e+163, 1e+164, 1e+165, 1e+166, 1e+167, 1e+168, 1e+169, 110   1e+160, 1e+161, 1e+162, 1e+163, 1e+164, 1e+165, 1e+166, 1e+167, 1e+168, 1e+169,
111   1e+170, 1e+171, 1e+172, 1e+173, 1e+174, 1e+175, 1e+176, 1e+177, 1e+178, 1e+179, 111   1e+170, 1e+171, 1e+172, 1e+173, 1e+174, 1e+175, 1e+176, 1e+177, 1e+178, 1e+179,
112   1e+180, 1e+181, 1e+182, 1e+183, 1e+184, 1e+185, 1e+186, 1e+187, 1e+188, 1e+189, 112   1e+180, 1e+181, 1e+182, 1e+183, 1e+184, 1e+185, 1e+186, 1e+187, 1e+188, 1e+189,
113   1e+190, 1e+191, 1e+192, 1e+193, 1e+194, 1e+195, 1e+196, 1e+197, 1e+198, 1e+199, 113   1e+190, 1e+191, 1e+192, 1e+193, 1e+194, 1e+195, 1e+196, 1e+197, 1e+198, 1e+199,
114   114  
115   1e+200, 1e+201, 1e+202, 1e+203, 1e+204, 1e+205, 1e+206, 1e+207, 1e+208, 1e+209, 115   1e+200, 1e+201, 1e+202, 1e+203, 1e+204, 1e+205, 1e+206, 1e+207, 1e+208, 1e+209,
116   1e+210, 1e+211, 1e+212, 1e+213, 1e+214, 1e+215, 1e+216, 1e+217, 1e+218, 1e+219, 116   1e+210, 1e+211, 1e+212, 1e+213, 1e+214, 1e+215, 1e+216, 1e+217, 1e+218, 1e+219,
117   1e+220, 1e+221, 1e+222, 1e+223, 1e+224, 1e+225, 1e+226, 1e+227, 1e+228, 1e+229, 117   1e+220, 1e+221, 1e+222, 1e+223, 1e+224, 1e+225, 1e+226, 1e+227, 1e+228, 1e+229,
118   1e+230, 1e+231, 1e+232, 1e+233, 1e+234, 1e+235, 1e+236, 1e+237, 1e+238, 1e+239, 118   1e+230, 1e+231, 1e+232, 1e+233, 1e+234, 1e+235, 1e+236, 1e+237, 1e+238, 1e+239,
119   1e+240, 1e+241, 1e+242, 1e+243, 1e+244, 1e+245, 1e+246, 1e+247, 1e+248, 1e+249, 119   1e+240, 1e+241, 1e+242, 1e+243, 1e+244, 1e+245, 1e+246, 1e+247, 1e+248, 1e+249,
120   1e+250, 1e+251, 1e+252, 1e+253, 1e+254, 1e+255, 1e+256, 1e+257, 1e+258, 1e+259, 120   1e+250, 1e+251, 1e+252, 1e+253, 1e+254, 1e+255, 1e+256, 1e+257, 1e+258, 1e+259,
121   1e+260, 1e+261, 1e+262, 1e+263, 1e+264, 1e+265, 1e+266, 1e+267, 1e+268, 1e+269, 121   1e+260, 1e+261, 1e+262, 1e+263, 1e+264, 1e+265, 1e+266, 1e+267, 1e+268, 1e+269,
122   1e+270, 1e+271, 1e+272, 1e+273, 1e+274, 1e+275, 1e+276, 1e+277, 1e+278, 1e+279, 122   1e+270, 1e+271, 1e+272, 1e+273, 1e+274, 1e+275, 1e+276, 1e+277, 1e+278, 1e+279,
123   1e+280, 1e+281, 1e+282, 1e+283, 1e+284, 1e+285, 1e+286, 1e+287, 1e+288, 1e+289, 123   1e+280, 1e+281, 1e+282, 1e+283, 1e+284, 1e+285, 1e+286, 1e+287, 1e+288, 1e+289,
124   1e+290, 1e+291, 1e+292, 1e+293, 1e+294, 1e+295, 1e+296, 1e+297, 1e+298, 1e+299, 124   1e+290, 1e+291, 1e+292, 1e+293, 1e+294, 1e+295, 1e+296, 1e+297, 1e+298, 1e+299,
125   125  
126   1e+300, 1e+301, 1e+302, 1e+303, 1e+304, 1e+305, 1e+306, 1e+307, 1e+308 }; 126   1e+300, 1e+301, 1e+302, 1e+303, 1e+304, 1e+305, 1e+306, 1e+307, 1e+308 };
127   127  
HITCBC 128   1035607 if( exp > 308 ) 128   1035607 if( exp > 308 )
129   { 129   {
HITCBC 130   455 return std::numeric_limits<double>::infinity(); 130   455 return std::numeric_limits<double>::infinity();
131   } 131   }
HITCBC 132   1035152 else if( exp < -308 ) 132   1035152 else if( exp < -308 )
133   { 133   {
134   // due to the way pow10 is used by dec_to_float, 134   // due to the way pow10 is used by dec_to_float,
135   // we can afford to return 0.0 here 135   // we can afford to return 0.0 here
HITCBC 136   151 return 0.0; 136   151 return 0.0;
137   } 137   }
138   else 138   else
139   { 139   {
HITCBC 140   1035001 exp += 308; 140   1035001 exp += 308;
HITCBC 141   1035001 BOOST_ASSERT(exp >= 0 && exp < 618); 141   1035001 BOOST_ASSERT(exp >= 0 && exp < 618);
HITCBC 142   1035001 return tab[exp]; 142   1035001 return tab[exp];
143   } 143   }
144   } 144   }
145   145  
146   inline 146   inline
147   double 147   double
HITCBC 148   1043157 dec_to_float( 148   1043157 dec_to_float(
149   std::uint64_t m, 149   std::uint64_t m,
150   std::int32_t e, 150   std::int32_t e,
151   bool neg) noexcept 151   bool neg) noexcept
152   { 152   {
153   // convert to double explicitly to silence warnings 153   // convert to double explicitly to silence warnings
HITCBC 154   1043157 double x = static_cast<double>(m); 154   1043157 double x = static_cast<double>(m);
HITCBC 155   1043157 if(neg) 155   1043157 if(neg)
HITCBC 156   17069 x = -x; 156   17069 x = -x;
157   157  
158   // pow10 returns infinity for large exponents, 158   // pow10 returns infinity for large exponents,
159   // and zero times infinity is NaN 159   // and zero times infinity is NaN
HITCBC 160   1043157 if(m == 0) 160   1043157 if(m == 0)
HITCBC 161   7550 return x; 161   7550 return x;
162   162  
HITCBC 163   1035607 if(e < -305) 163   1035607 if(e < -305)
164   { 164   {
HITCBC 165   5269 x *= 1e-305 ; 165   5269 x *= 1e-305 ;
HITCBC 166   5269 e += 305; 166   5269 e += 305;
167   } 167   }
168   168  
HITCBC 169   1035607 if(e >= -22 && e < 0) 169   1035607 if(e >= -22 && e < 0)
HITCBC 170   57637 return x / pow10(-e); 170   57637 return x / pow10(-e);
171   171  
HITCBC 172   977970 return x * pow10(e); 172   977970 return x * pow10(e);
173   } 173   }
174   174  
175   inline 175   inline
176   bool 176   bool
177   is_control(char c) noexcept 177   is_control(char c) noexcept
178   { 178   {
179   return static_cast<unsigned char>(c) < 32; 179   return static_cast<unsigned char>(c) < 32;
180   } 180   }
181   181  
182   inline 182   inline
183   int 183   int
HITCBC 184   66931 hex_digit(unsigned char c) noexcept 184   66931 hex_digit(unsigned char c) noexcept
185   { 185   {
186   // by Peter Dimov 186   // by Peter Dimov
HITCBC 187   66931 if( c >= '0' && c <= '9' ) 187   66931 if( c >= '0' && c <= '9' )
HITCBC 188   35759 return c - '0'; 188   35759 return c - '0';
HITCBC 189   31172 c &= ~0x20; 189   31172 c &= ~0x20;
HITCBC 190   31172 if( c >= 'A' && c <= 'F' ) 190   31172 if( c >= 'A' && c <= 'F' )
HITCBC 191   30562 return 10 + c - 'A'; 191   30562 return 10 + c - 'A';
HITCBC 192   610 return -1; 192   610 return -1;
193   } 193   }
194   194  
195   } // detail 195   } // detail
196   196  
197   //---------------------------------------------------------- 197   //----------------------------------------------------------
198   198  
199   template< class Handler > 199   template< class Handler >
200   template< bool StackEmpty_, char First_ > 200   template< bool StackEmpty_, char First_ >
201   struct basic_parser<Handler>:: 201   struct basic_parser<Handler>::
202   parse_number_helper 202   parse_number_helper
203   { 203   {
204   basic_parser* parser; 204   basic_parser* parser;
205   char const* p; 205   char const* p;
206   206  
207   template< std::size_t N > 207   template< std::size_t N >
208   char const* 208   char const*
HITCBC 209   10516036 operator()( mp11::mp_size_t<N> ) const 209   10516036 operator()( mp11::mp_size_t<N> ) const
210   { 210   {
HITCBC 211   21026567 return parser->parse_number( 211   21026567 return parser->parse_number(
HITCBC 212   10516036 p, 212   10516036 p,
213   std::integral_constant<bool, StackEmpty_>(), 213   std::integral_constant<bool, StackEmpty_>(),
214   std::integral_constant<char, First_>(), 214   std::integral_constant<char, First_>(),
215   std::integral_constant< 215   std::integral_constant<
HITCBC 216   10510532 number_precision, static_cast<number_precision>(N)>() ); 216   10510532 number_precision, static_cast<number_precision>(N)>() );
217   } 217   }
218   }; 218   };
219   219  
220   //---------------------------------------------------------- 220   //----------------------------------------------------------
221   221  
222   template<class Handler> 222   template<class Handler>
223   void 223   void
HITCBC 224   8602565 basic_parser<Handler>:: 224   8602565 basic_parser<Handler>::
225   reserve() 225   reserve()
226   { 226   {
HITCBC 227   8602565 if(BOOST_JSON_LIKELY( 227   8602565 if(BOOST_JSON_LIKELY(
228   ! st_.empty())) 228   ! st_.empty()))
HITCBC 229   37534 return; 229   37534 return;
230   // Reserve the largest stack we need, 230   // Reserve the largest stack we need,
231   // to avoid reallocation during suspend. 231   // to avoid reallocation during suspend.
HITCBC 232   17130062 st_.reserve( 232   17130062 st_.reserve(
233   sizeof(state) + // document parsing state 233   sizeof(state) + // document parsing state
234   (sizeof(state) + 234   (sizeof(state) +
HITCBC 235   8565031 sizeof(std::size_t)) * depth() + // array and object state + size 235   8565031 sizeof(std::size_t)) * depth() + // array and object state + size
236   sizeof(state) + // value parsing state 236   sizeof(state) + // value parsing state
237   sizeof(std::size_t) + // string size 237   sizeof(std::size_t) + // string size
238   sizeof(state)); // comment state 238   sizeof(state)); // comment state
239   } 239   }
240   240  
241   //---------------------------------------------------------- 241   //----------------------------------------------------------
242   // 242   //
243   // The sentinel value is returned by parse functions 243   // The sentinel value is returned by parse functions
244   // to indicate that the parser failed, or suspended. 244   // to indicate that the parser failed, or suspended.
245   // this is used as it is distinct from all valid values 245   // this is used as it is distinct from all valid values
246   // for data in write 246   // for data in write
247   247  
248   template<class Handler> 248   template<class Handler>
249   const char* 249   const char*
HITCBC 250   47301850 basic_parser<Handler>:: 250   47301850 basic_parser<Handler>::
251   sentinel() 251   sentinel()
252   { 252   {
253   // the "+1" ensures that the returned pointer is unique even if 253   // the "+1" ensures that the returned pointer is unique even if
254   // the given input buffer borders on this object 254   // the given input buffer borders on this object
255   return reinterpret_cast< 255   return reinterpret_cast<
HITCBC 256   47301850 const char*>(this) + 1; 256   47301850 const char*>(this) + 1;
257   } 257   }
258   258  
259   template<class Handler> 259   template<class Handler>
260   bool 260   bool
HITCBC 261   10852199 basic_parser<Handler>:: 261   10852199 basic_parser<Handler>::
262   incomplete( 262   incomplete(
263   const detail::const_stream_wrapper& cs) 263   const detail::const_stream_wrapper& cs)
264   { 264   {
HITCBC 265   10852199 return cs.begin() == sentinel(); 265   10852199 return cs.begin() == sentinel();
266   } 266   }
267   267  
268   //---------------------------------------------------------- 268   //----------------------------------------------------------
269   // 269   //
270   // These functions are declared with the BOOST_NOINLINE 270   // These functions are declared with the BOOST_NOINLINE
271   // attribute to avoid polluting the parsers hot-path. 271   // attribute to avoid polluting the parsers hot-path.
272   // They return the canary value to indicate suspension 272   // They return the canary value to indicate suspension
273   // or failure. 273   // or failure.
274   274  
275   template<class Handler> 275   template<class Handler>
276   const char* 276   const char*
277   basic_parser<Handler>:: 277   basic_parser<Handler>::
278   suspend_or_fail(state st) 278   suspend_or_fail(state st)
279   { 279   {
280   if(BOOST_JSON_LIKELY( 280   if(BOOST_JSON_LIKELY(
281   ! ec_ && more_)) 281   ! ec_ && more_))
282   { 282   {
283   // suspend 283   // suspend
284   reserve(); 284   reserve();
285   st_.push_unchecked(st); 285   st_.push_unchecked(st);
286   } 286   }
287   return sentinel(); 287   return sentinel();
288   } 288   }
289   289  
290   template<class Handler> 290   template<class Handler>
291   const char* 291   const char*
HITCBC 292   56196 basic_parser<Handler>:: 292   56196 basic_parser<Handler>::
293   suspend_or_fail( 293   suspend_or_fail(
294   state st, 294   state st,
295   std::size_t n) 295   std::size_t n)
296   { 296   {
HITCBC 297   56196 if(BOOST_JSON_LIKELY( 297   56196 if(BOOST_JSON_LIKELY(
298   ! ec_ && more_)) 298   ! ec_ && more_))
299   { 299   {
300   // suspend 300   // suspend
HITCBC 301   35878 reserve(); 301   35878 reserve();
HITCBC 302   35878 st_.push_unchecked(n); 302   35878 st_.push_unchecked(n);
HITCBC 303   35878 st_.push_unchecked(st); 303   35878 st_.push_unchecked(st);
304   } 304   }
HITCBC 305   56196 return sentinel(); 305   56196 return sentinel();
306   } 306   }
307   307  
308   308  
309   template<class Handler> 309   template<class Handler>
310   const char* 310   const char*
HITCBC 311   19076 basic_parser<Handler>:: 311   19076 basic_parser<Handler>::
312   fail(const char* p) noexcept 312   fail(const char* p) noexcept
313   { 313   {
HITCBC 314   19076 BOOST_ASSERT( p != sentinel() ); 314   19076 BOOST_ASSERT( p != sentinel() );
HITCBC 315   19076 end_ = p; 315   19076 end_ = p;
HITCBC 316   19076 return sentinel(); 316   19076 return sentinel();
317   } 317   }
318   318  
319   template<class Handler> 319   template<class Handler>
320   const char* 320   const char*
HITCBC 321   7781 basic_parser<Handler>:: 321   7781 basic_parser<Handler>::
322   fail( 322   fail(
323   const char* p, 323   const char* p,
324   error ev, 324   error ev,
325   source_location const* loc) noexcept 325   source_location const* loc) noexcept
326   { 326   {
HITCBC 327   7781 BOOST_ASSERT( p != sentinel() ); 327   7781 BOOST_ASSERT( p != sentinel() );
HITCBC 328   7781 end_ = p; 328   7781 end_ = p;
HITCBC 329   7781 ec_.assign(ev, loc); 329   7781 ec_.assign(ev, loc);
HITCBC 330   7781 return sentinel(); 330   7781 return sentinel();
331   } 331   }
332   332  
333   template<class Handler> 333   template<class Handler>
334   const char* 334   const char*
HITCBC 335   11405 basic_parser<Handler>:: 335   11405 basic_parser<Handler>::
336   maybe_suspend( 336   maybe_suspend(
337   const char* p, 337   const char* p,
338   state st) 338   state st)
339   { 339   {
HITCBC 340   11405 if( p != sentinel() ) 340   11405 if( p != sentinel() )
HITCBC 341   9487 end_ = p; 341   9487 end_ = p;
HITCBC 342   11405 if(BOOST_JSON_LIKELY(more_)) 342   11405 if(BOOST_JSON_LIKELY(more_))
343   { 343   {
344   // suspend 344   // suspend
HITCBC 345   11132 reserve(); 345   11132 reserve();
HITCBC 346   11132 st_.push_unchecked(st); 346   11132 st_.push_unchecked(st);
347   } 347   }
HITCBC 348   11405 return sentinel(); 348   11405 return sentinel();
349   } 349   }
350   350  
351   template<class Handler> 351   template<class Handler>
352   const char* 352   const char*
HITCBC 353   41269 basic_parser<Handler>:: 353   41269 basic_parser<Handler>::
354   maybe_suspend( 354   maybe_suspend(
355   const char* p, 355   const char* p,
356   state st, 356   state st,
357   std::size_t n) 357   std::size_t n)
358   { 358   {
HITCBC 359   41269 BOOST_ASSERT( p != sentinel() ); 359   41269 BOOST_ASSERT( p != sentinel() );
HITCBC 360   41269 end_ = p; 360   41269 end_ = p;
HITCBC 361   41269 if(BOOST_JSON_LIKELY(more_)) 361   41269 if(BOOST_JSON_LIKELY(more_))
362   { 362   {
363   // suspend 363   // suspend
HITCBC 364   40861 reserve(); 364   40861 reserve();
HITCBC 365   40861 st_.push_unchecked(n); 365   40861 st_.push_unchecked(n);
HITCBC 366   40861 st_.push_unchecked(st); 366   40861 st_.push_unchecked(st);
367   } 367   }
HITCBC 368   41269 return sentinel(); 368   41269 return sentinel();
369   } 369   }
370   370  
371   template<class Handler> 371   template<class Handler>
372   const char* 372   const char*
HITCBC 373   1132 basic_parser<Handler>:: 373   1132 basic_parser<Handler>::
374   maybe_suspend( 374   maybe_suspend(
375   const char* p, 375   const char* p,
376   state st, 376   state st,
377   const number& num) 377   const number& num)
378   { 378   {
HITCBC 379   1132 BOOST_ASSERT( p != sentinel() ); 379   1132 BOOST_ASSERT( p != sentinel() );
HITCBC 380   1132 end_ = p; 380   1132 end_ = p;
HITCBC 381   1132 if(BOOST_JSON_LIKELY(more_)) 381   1132 if(BOOST_JSON_LIKELY(more_))
382   { 382   {
383   // suspend 383   // suspend
HITCBC 384   1132 num_ = num; 384   1132 num_ = num;
HITCBC 385   1132 reserve(); 385   1132 reserve();
HITCBC 386   1132 st_.push_unchecked(st);; 386   1132 st_.push_unchecked(st);;
387   } 387   }
HITCBC 388   1132 return sentinel(); 388   1132 return sentinel();
389   } 389   }
390   390  
391   template<class Handler> 391   template<class Handler>
392   const char* 392   const char*
HITCBC 393   88665 basic_parser<Handler>:: 393   88665 basic_parser<Handler>::
394   suspend( 394   suspend(
395   const char* p, 395   const char* p,
396   state st) 396   state st)
397   { 397   {
HITCBC 398   88665 BOOST_ASSERT( p != sentinel() ); 398   88665 BOOST_ASSERT( p != sentinel() );
HITCBC 399   88665 end_ = p; 399   88665 end_ = p;
400   // suspend 400   // suspend
HITCBC 401   88665 reserve(); 401   88665 reserve();
HITCBC 402   88665 st_.push_unchecked(st); 402   88665 st_.push_unchecked(st);
HITCBC 403   88665 return sentinel(); 403   88665 return sentinel();
404   } 404   }
405   405  
406   template<class Handler> 406   template<class Handler>
407   const char* 407   const char*
HITCBC 408   8424897 basic_parser<Handler>:: 408   8424897 basic_parser<Handler>::
409   suspend( 409   suspend(
410   const char* p, 410   const char* p,
411   state st, 411   state st,
412   const number& num) 412   const number& num)
413   { 413   {
HITCBC 414   8424897 BOOST_ASSERT( p != sentinel() ); 414   8424897 BOOST_ASSERT( p != sentinel() );
HITCBC 415   8424897 end_ = p; 415   8424897 end_ = p;
416   // suspend 416   // suspend
HITCBC 417   8424897 num_ = num; 417   8424897 num_ = num;
HITCBC 418   8424897 reserve(); 418   8424897 reserve();
HITCBC 419   8424897 st_.push_unchecked(st); 419   8424897 st_.push_unchecked(st);
HITCBC 420   8424897 return sentinel(); 420   8424897 return sentinel();
421   } 421   }
422   422  
423   template<class Handler> 423   template<class Handler>
424   template< 424   template<
425   bool StackEmpty_/*, 425   bool StackEmpty_/*,
426   bool Terminal_*/> 426   bool Terminal_*/>
427   const char* 427   const char*
HITCBC 428   21806 basic_parser<Handler>:: 428   21806 basic_parser<Handler>::
429   parse_comment(const char* p, 429   parse_comment(const char* p,
430   std::integral_constant<bool, StackEmpty_> stack_empty, 430   std::integral_constant<bool, StackEmpty_> stack_empty,
431   /*std::integral_constant<bool, Terminal_>*/ bool terminal) 431   /*std::integral_constant<bool, Terminal_>*/ bool terminal)
432   { 432   {
HITCBC 433   21806 detail::const_stream_wrapper cs(p, end_); 433   21806 detail::const_stream_wrapper cs(p, end_);
HITCBC 434   21806 const char* start = cs.begin(); 434   21806 const char* start = cs.begin();
435   std::size_t remain; 435   std::size_t remain;
HITCBC 436   21806 if(! stack_empty && ! st_.empty()) 436   21806 if(! stack_empty && ! st_.empty())
437   { 437   {
438   state st; 438   state st;
HITCBC 439   3555 st_.pop(st); 439   3555 st_.pop(st);
HITCBC 440   3555 switch(st) 440   3555 switch(st)
441   { 441   {
442   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE 442   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE
HITCBC 443   540 case state::com1: goto do_com1; 443   540 case state::com1: goto do_com1;
HITCBC 444   2361 case state::com2: goto do_com2; 444   2361 case state::com2: goto do_com2;
HITCBC 445   438 case state::com3: goto do_com3; 445   438 case state::com3: goto do_com3;
HITCBC 446   216 case state::com4: goto do_com4; 446   216 case state::com4: goto do_com4;
447   } 447   }
448   } 448   }
HITCBC 449   18251 BOOST_ASSERT(*cs == '/'); 449   18251 BOOST_ASSERT(*cs == '/');
HITCBC 450   18251 ++cs; 450   18251 ++cs;
HITCBC 451   18791 do_com1: 451   18791 do_com1:
HITCBC 452   18791 if(BOOST_JSON_UNLIKELY(! cs)) 452   18791 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 453   557 return maybe_suspend(cs.begin(), state::com1); 453   557 return maybe_suspend(cs.begin(), state::com1);
HITCBC 454   18234 switch(*cs) 454   18234 switch(*cs)
455   { 455   {
HITCBC 456   5 default: 456   5 default:
457   { 457   {
458   BOOST_STATIC_CONSTEXPR source_location loc 458   BOOST_STATIC_CONSTEXPR source_location loc
459   = BOOST_CURRENT_LOCATION; 459   = BOOST_CURRENT_LOCATION;
HITCBC 460   5 return fail(cs.begin(), error::syntax, &loc); 460   5 return fail(cs.begin(), error::syntax, &loc);
461   } 461   }
HITCBC 462   10545 case '/': 462   10545 case '/':
HITCBC 463   10545 ++cs; 463   10545 ++cs;
HITCBC 464   12906 do_com2: 464   12906 do_com2:
465   // KRYSTIAN TODO: this is a mess, we have to fix this 465   // KRYSTIAN TODO: this is a mess, we have to fix this
HITCBC 466   12906 remain = cs.remain(); 466   12906 remain = cs.remain();
HITCBC 467   25812 cs = remain ? static_cast<const char*>( 467   25812 cs = remain ? static_cast<const char*>(
HITCBC 468   12906 std::memchr(cs.begin(), '\n', remain)) : sentinel(); 468   12906 std::memchr(cs.begin(), '\n', remain)) : sentinel();
HITCBC 469   12906 if(! cs.begin()) 469   12906 if(! cs.begin())
HITCBC 470   2179 cs = sentinel(); 470   2179 cs = sentinel();
HITCBC 471   12906 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 471   12906 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
472   { 472   {
473   // if the doc does not terminate 473   // if the doc does not terminate
474   // with a newline, treat it as the 474   // with a newline, treat it as the
475   // end of the comment 475   // end of the comment
HITCBC 476   2612 if(terminal && ! more_) 476   2612 if(terminal && ! more_)
477   { 477   {
HITCBC 478   39 if(BOOST_JSON_UNLIKELY(! h_.on_comment( 478   39 if(BOOST_JSON_UNLIKELY(! h_.on_comment(
479   {start, cs.remain(start)}, ec_))) 479   {start, cs.remain(start)}, ec_)))
HITCBC 480   2 return fail(cs.end()); 480   2 return fail(cs.end());
HITCBC 481   35 return cs.end(); 481   35 return cs.end();
482   } 482   }
HITCBC 483   2573 if(BOOST_JSON_UNLIKELY(! h_.on_comment_part( 483   2573 if(BOOST_JSON_UNLIKELY(! h_.on_comment_part(
484   {start, cs.remain(start)}, ec_))) 484   {start, cs.remain(start)}, ec_)))
HITCBC 485   96 return fail(cs.end()); 485   96 return fail(cs.end());
HITCBC 486   2381 if(terminal) 486   2381 if(terminal)
HITCBC 487   106 return suspend(cs.end(), state::com2); 487   106 return suspend(cs.end(), state::com2);
HITCBC 488   2275 return maybe_suspend(cs.end(), state::com2); 488   2275 return maybe_suspend(cs.end(), state::com2);
489   } 489   }
HITCBC 490   10294 break; 490   10294 break;
HITCBC 491   1684 case '*': 491   1684 case '*':
492   do 492   do
493   { 493   {
HITCBC 494   9368 ++cs; 494   9368 ++cs;
HITCBC 495   9806 do_com3: 495   9806 do_com3:
496   // KRYSTIAN TODO: this is a mess, we have to fix this 496   // KRYSTIAN TODO: this is a mess, we have to fix this
HITCBC 497   9806 remain = cs.remain(); 497   9806 remain = cs.remain();
HITCBC 498   19612 cs = remain ? static_cast<const char*>( 498   19612 cs = remain ? static_cast<const char*>(
HITCBC 499   9806 std::memchr(cs.begin(), '*', remain)) : sentinel(); 499   9806 std::memchr(cs.begin(), '*', remain)) : sentinel();
HITCBC 500   9806 if(! cs.begin()) 500   9806 if(! cs.begin())
HITCBC 501   242 cs = sentinel(); 501   242 cs = sentinel();
502   // stopped inside a c comment 502   // stopped inside a c comment
HITCBC 503   9806 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 503   9806 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
504   { 504   {
HITCBC 505   503 if(BOOST_JSON_UNLIKELY(! h_.on_comment_part( 505   503 if(BOOST_JSON_UNLIKELY(! h_.on_comment_part(
506   {start, cs.remain(start)}, ec_))) 506   {start, cs.remain(start)}, ec_)))
HITCBC 507   30 return fail(cs.end()); 507   30 return fail(cs.end());
HITCBC 508   443 return maybe_suspend(cs.end(), state::com3); 508   443 return maybe_suspend(cs.end(), state::com3);
509   } 509   }
510   // found a asterisk, check if the next char is a slash 510   // found a asterisk, check if the next char is a slash
HITCBC 511   9303 ++cs; 511   9303 ++cs;
HITCBC 512   9519 do_com4: 512   9519 do_com4:
HITCBC 513   9519 if(BOOST_JSON_UNLIKELY(! cs)) 513   9519 if(BOOST_JSON_UNLIKELY(! cs))
514   { 514   {
HITCBC 515   259 if(BOOST_JSON_UNLIKELY(! h_.on_comment_part( 515   259 if(BOOST_JSON_UNLIKELY(! h_.on_comment_part(
516   {start, cs.used(start)}, ec_))) 516   {start, cs.used(start)}, ec_)))
HITCBC 517   18 return fail(cs.begin()); 517   18 return fail(cs.begin());
HITCBC 518   223 return maybe_suspend(cs.begin(), state::com4); 518   223 return maybe_suspend(cs.begin(), state::com4);
519   } 519   }
520   } 520   }
HITCBC 521   9260 while(*cs != '/'); 521   9260 while(*cs != '/');
522   } 522   }
HITCBC 523   17870 ++cs; 523   17870 ++cs;
HITCBC 524   17870 if(BOOST_JSON_UNLIKELY(! h_.on_comment( 524   17870 if(BOOST_JSON_UNLIKELY(! h_.on_comment(
525   {start, cs.used(start)}, ec_))) 525   {start, cs.used(start)}, ec_)))
HITCBC 526   968 return fail(cs.begin()); 526   968 return fail(cs.begin());
HITCBC 527   15934 return cs.begin(); 527   15934 return cs.begin();
528   } 528   }
529   529  
530   template<class Handler> 530   template<class Handler>
531   template<bool StackEmpty_> 531   template<bool StackEmpty_>
532   const char* 532   const char*
HITCBC 533   10710684 basic_parser<Handler>:: 533   10710684 basic_parser<Handler>::
534   parse_document(const char* p, 534   parse_document(const char* p,
535   std::integral_constant<bool, StackEmpty_> stack_empty) 535   std::integral_constant<bool, StackEmpty_> stack_empty)
536   { 536   {
HITCBC 537   10710684 detail::const_stream_wrapper cs(p, end_); 537   10710684 detail::const_stream_wrapper cs(p, end_);
HITCBC 538   10710684 if(! stack_empty && ! st_.empty()) 538   10710684 if(! stack_empty && ! st_.empty())
539   { 539   {
540   state st; 540   state st;
HITCBC 541   8561549 st_.peek(st); 541   8561549 st_.peek(st);
HITCBC 542   8561549 switch(st) 542   8561549 switch(st)
543   { 543   {
HITCBC 544   8475476 default: goto do_doc2; 544   8475476 default: goto do_doc2;
HITCBC 545   601 case state::doc1: 545   601 case state::doc1:
HITCBC 546   601 st_.pop(st); 546   601 st_.pop(st);
HITCBC 547   601 goto do_doc1; 547   601 goto do_doc1;
HITCBC 548   85252 case state::doc3: 548   85252 case state::doc3:
HITCBC 549   85252 st_.pop(st); 549   85252 st_.pop(st);
HITCBC 550   85252 goto do_doc3; 550   85252 goto do_doc3;
HITCBC 551   220 case state::com1: case state::com2: 551   220 case state::com1: case state::com2:
552   case state::com3: case state::com4: 552   case state::com3: case state::com4:
HITCBC 553   220 goto do_doc4; 553   220 goto do_doc4;
554   } 554   }
555   } 555   }
HITCBC 556   2149135 do_doc1: 556   2149135 do_doc1:
HITCBC 557   2149736 cs = detail::count_whitespace(cs.begin(), cs.end()); 557   2149736 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 558   2149736 if(BOOST_JSON_UNLIKELY(! cs)) 558   2149736 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 559   633 return maybe_suspend(cs.begin(), state::doc1); 559   633 return maybe_suspend(cs.begin(), state::doc1);
HITCBC 560   2149103 do_doc2: 560   2149103 do_doc2:
HITCBC 561   10624579 switch(+opt_.allow_comments | 561   10624579 switch(+opt_.allow_comments |
HITCBC 562   10624579 (opt_.allow_trailing_commas << 1) | 562   10624579 (opt_.allow_trailing_commas << 1) |
HITCBC 563   10624579 (opt_.allow_invalid_utf8 << 2)) 563   10624579 (opt_.allow_invalid_utf8 << 2))
564   { 564   {
565   // no extensions 565   // no extensions
HITCBC 566   10600800 default: 566   10600800 default:
HITCBC 567   10600800 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::false_type(), std::false_type(), opt_.allow_invalid_utf16); 567   10600800 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::false_type(), std::false_type(), opt_.allow_invalid_utf16);
HITCBC 568   10585578 break; 568   10585578 break;
569   // comments 569   // comments
HITCBC 570   13648 case 1: 570   13648 case 1:
HITCBC 571   13648 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::false_type(), std::false_type(), opt_.allow_invalid_utf16); 571   13648 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::false_type(), std::false_type(), opt_.allow_invalid_utf16);
HITCBC 572   11380 break; 572   11380 break;
573   // trailing 573   // trailing
HITCBC 574   6710 case 2: 574   6710 case 2:
HITCBC 575   6710 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::true_type(), std::false_type(), opt_.allow_invalid_utf16); 575   6710 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::true_type(), std::false_type(), opt_.allow_invalid_utf16);
HITCBC 576   5117 break; 576   5117 break;
577   // comments & trailing 577   // comments & trailing
HITCBC 578   761 case 3: 578   761 case 3:
HITCBC 579   761 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::true_type(), std::false_type(), opt_.allow_invalid_utf16); 579   761 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::true_type(), std::false_type(), opt_.allow_invalid_utf16);
HITCBC 580   761 break; 580   761 break;
581   // skip validation 581   // skip validation
HITCBC 582   760 case 4: 582   760 case 4:
HITCBC 583   760 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::false_type(), std::true_type(), opt_.allow_invalid_utf16); 583   760 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::false_type(), std::true_type(), opt_.allow_invalid_utf16);
HITCBC 584   760 break; 584   760 break;
585   // comments & skip validation 585   // comments & skip validation
HITCBC 586   760 case 5: 586   760 case 5:
HITCBC 587   760 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::false_type(), std::true_type(), opt_.allow_invalid_utf16); 587   760 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::false_type(), std::true_type(), opt_.allow_invalid_utf16);
HITCBC 588   760 break; 588   760 break;
589   // trailing & skip validation 589   // trailing & skip validation
HITCBC 590   760 case 6: 590   760 case 6:
HITCBC 591   760 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::true_type(), std::true_type(), opt_.allow_invalid_utf16); 591   760 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::true_type(), std::true_type(), opt_.allow_invalid_utf16);
HITCBC 592   760 break; 592   760 break;
593   // comments & trailing & skip validation 593   // comments & trailing & skip validation
HITCBC 594   380 case 7: 594   380 case 7:
HITCBC 595   380 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::true_type(), std::true_type(), opt_.allow_invalid_utf16); 595   380 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::true_type(), std::true_type(), opt_.allow_invalid_utf16);
HITCBC 596   380 break; 596   380 break;
597   } 597   }
HITCBC 598   10605496 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 598   10605496 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
599   // the appropriate state has already been pushed into stack 599   // the appropriate state has already been pushed into stack
HITCBC 600   8502776 return sentinel(); 600   8502776 return sentinel();
HITCBC 601   2102720 do_doc3: 601   2102720 do_doc3:
HITCBC 602   2188304 cs = detail::count_whitespace(cs.begin(), cs.end()); 602   2188304 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 603   2188304 if(BOOST_JSON_UNLIKELY(! cs)) 603   2188304 if(BOOST_JSON_UNLIKELY(! cs))
604   { 604   {
HITCBC 605   2185706 if(more_) 605   2185706 if(more_)
HITCBC 606   88559 return suspend(cs.begin(), state::doc3); 606   88559 return suspend(cs.begin(), state::doc3);
607   } 607   }
HITCBC 608   2598 else if(opt_.allow_comments && *cs == '/') 608   2598 else if(opt_.allow_comments && *cs == '/')
609   { 609   {
HITCBC 610   536 do_doc4: 610   536 do_doc4:
HITCBC 611   756 cs = parse_comment(cs.begin(), stack_empty, std::true_type()); 611   756 cs = parse_comment(cs.begin(), stack_empty, std::true_type());
HITCBC 612   671 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 612   671 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 613   339 return sentinel(); 613   339 return sentinel();
HITCBC 614   332 goto do_doc3; 614   332 goto do_doc3;
615   } 615   }
HITCBC 616   2099209 return cs.begin(); 616   2099209 return cs.begin();
617   } 617   }
618   618  
619   template<class Handler> 619   template<class Handler>
620   template< 620   template<
621   bool StackEmpty_, 621   bool StackEmpty_,
622   bool AllowComments_/*, 622   bool AllowComments_/*,
623   bool AllowTrailing_, 623   bool AllowTrailing_,
624   bool AllowBadUTF8_*/> 624   bool AllowBadUTF8_*/>
625   const char* 625   const char*
HITCBC 626   10742281 basic_parser<Handler>:: 626   10742281 basic_parser<Handler>::
627   parse_value(const char* p, 627   parse_value(const char* p,
628   std::integral_constant<bool, StackEmpty_> stack_empty, 628   std::integral_constant<bool, StackEmpty_> stack_empty,
629   std::integral_constant<bool, AllowComments_> allow_comments, 629   std::integral_constant<bool, AllowComments_> allow_comments,
630   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 630   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
631   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 631   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
632   bool allow_bad_utf16) 632   bool allow_bad_utf16)
633   { 633   {
HITCBC 634   10742281 if(stack_empty || st_.empty()) 634   10742281 if(stack_empty || st_.empty())
635   { 635   {
HITCBC 636   2248406 loop: 636   2248406 loop:
HITCBC 637   2253322 switch(*p) 637   2253322 switch(*p)
638   { 638   {
HITCBC 639   22761 case '0': 639   22761 case '0':
HITCBC 640   22761 return mp11::mp_with_index<3>( 640   22761 return mp11::mp_with_index<3>(
HITCBC 641   22761 static_cast<unsigned char>(opt_.numbers), 641   22761 static_cast<unsigned char>(opt_.numbers),
HITCBC 642   22100 parse_number_helper<true, '0'>{ this, p }); 642   22100 parse_number_helper<true, '0'>{ this, p });
HITCBC 643   25185 case '-': 643   25185 case '-':
HITCBC 644   25185 return mp11::mp_with_index<3>( 644   25185 return mp11::mp_with_index<3>(
HITCBC 645   25185 static_cast<unsigned char>(opt_.numbers), 645   25185 static_cast<unsigned char>(opt_.numbers),
HITCBC 646   24073 parse_number_helper<true, '-'>{ this, p }); 646   24073 parse_number_helper<true, '-'>{ this, p });
HITCBC 647   2042064 case '1': case '2': case '3': 647   2042064 case '1': case '2': case '3':
648   case '4': case '5': case '6': 648   case '4': case '5': case '6':
649   case '7': case '8': case '9': 649   case '7': case '8': case '9':
HITCBC 650   2042064 return mp11::mp_with_index<3>( 650   2042064 return mp11::mp_with_index<3>(
HITCBC 651   2042064 static_cast<unsigned char>(opt_.numbers), 651   2042064 static_cast<unsigned char>(opt_.numbers),
HITCBC 652   2039188 parse_number_helper<true, '+'>{ this, p }); 652   2039188 parse_number_helper<true, '+'>{ this, p });
HITCBC 653   11381 case 'n': 653   11381 case 'n':
HITCBC 654   11381 return parse_literal( p, detail::literals_c<detail::literals::null>() ); 654   11381 return parse_literal( p, detail::literals_c<detail::literals::null>() );
HITCBC 655   664 case 't': 655   664 case 't':
HITCBC 656   664 return parse_literal( p, detail::literals_c<detail::literals::true_>() ); 656   664 return parse_literal( p, detail::literals_c<detail::literals::true_>() );
HITCBC 657   722 case 'f': 657   722 case 'f':
HITCBC 658   722 return parse_literal( p, detail::literals_c<detail::literals::false_>() ); 658   722 return parse_literal( p, detail::literals_c<detail::literals::false_>() );
HITCBC 659   681 case 'I': 659   681 case 'I':
HITCBC 660   681 if( !opt_.allow_infinity_and_nan ) 660   681 if( !opt_.allow_infinity_and_nan )
661   { 661   {
662   BOOST_STATIC_CONSTEXPR source_location loc 662   BOOST_STATIC_CONSTEXPR source_location loc
663   = BOOST_CURRENT_LOCATION; 663   = BOOST_CURRENT_LOCATION;
HITCBC 664   24 return fail(p, error::syntax, &loc); 664   24 return fail(p, error::syntax, &loc);
665   } 665   }
HITCBC 666   657 return parse_literal( p, detail::literals_c<detail::literals::infinity>() ); 666   657 return parse_literal( p, detail::literals_c<detail::literals::infinity>() );
HITCBC 667   231 case 'N': 667   231 case 'N':
HITCBC 668   231 if( !opt_.allow_infinity_and_nan ) 668   231 if( !opt_.allow_infinity_and_nan )
669   { 669   {
670   BOOST_STATIC_CONSTEXPR source_location loc 670   BOOST_STATIC_CONSTEXPR source_location loc
671   = BOOST_CURRENT_LOCATION; 671   = BOOST_CURRENT_LOCATION;
HITCBC 672   30 return fail(p, error::syntax, &loc); 672   30 return fail(p, error::syntax, &loc);
673   } 673   }
HITCBC 674   201 return parse_literal(p, detail::literals_c<detail::literals::nan>() ); 674   201 return parse_literal(p, detail::literals_c<detail::literals::nan>() );
HITCBC 675   47587 case '"': 675   47587 case '"':
HITCBC 676   47587 return parse_string(p, std::true_type(), std::false_type(), allow_bad_utf8, allow_bad_utf16); 676   47587 return parse_string(p, std::true_type(), std::false_type(), allow_bad_utf8, allow_bad_utf16);
HITCBC 677   20641 case '[': 677   20641 case '[':
HITCBC 678   20641 return parse_array(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 678   20641 return parse_array(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
HITCBC 679   74138 case '{': 679   74138 case '{':
HITCBC 680   74138 return parse_object(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 680   74138 return parse_object(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
HITCBC 681   6146 case '/': 681   6146 case '/':
HITCBC 682   6146 if(! allow_comments) 682   6146 if(! allow_comments)
683   { 683   {
684   BOOST_STATIC_CONSTEXPR source_location loc 684   BOOST_STATIC_CONSTEXPR source_location loc
685   = BOOST_CURRENT_LOCATION; 685   = BOOST_CURRENT_LOCATION;
HITCBC 686   284 return fail(p, error::syntax, &loc); 686   284 return fail(p, error::syntax, &loc);
687   } 687   }
HITCBC 688   5862 p = parse_comment(p, stack_empty, std::false_type()); 688   5862 p = parse_comment(p, stack_empty, std::false_type());
689   // KRYSTIAN NOTE: incomplete takes const_stream, we either 689   // KRYSTIAN NOTE: incomplete takes const_stream, we either
690   // can add an overload, change the existing one to take a pointer, 690   // can add an overload, change the existing one to take a pointer,
691   // or just leave it as is 691   // or just leave it as is
HITCBC 692   5623 if(BOOST_JSON_UNLIKELY(p == sentinel())) 692   5623 if(BOOST_JSON_UNLIKELY(p == sentinel()))
HITCBC 693   604 return maybe_suspend(p, state::val2); 693   604 return maybe_suspend(p, state::val2);
694   BOOST_FALLTHROUGH; 694   BOOST_FALLTHROUGH;
695   case ' ': 695   case ' ':
696   case '\t': 696   case '\t':
697   case '\n': 697   case '\n':
698   case '\r': 698   case '\r':
HITCBC 699   5035 p = detail::count_whitespace(p, end_); 699   5035 p = detail::count_whitespace(p, end_);
HITCBC 700   5035 if(BOOST_JSON_UNLIKELY(p == end_)) 700   5035 if(BOOST_JSON_UNLIKELY(p == end_))
HITCBC 701   119 return maybe_suspend(p, state::val1); 701   119 return maybe_suspend(p, state::val1);
HITCBC 702   4916 goto loop; 702   4916 goto loop;
HITCBC 703   1105 default: 703   1105 default:
704   { 704   {
705   BOOST_STATIC_CONSTEXPR source_location loc 705   BOOST_STATIC_CONSTEXPR source_location loc
706   = BOOST_CURRENT_LOCATION; 706   = BOOST_CURRENT_LOCATION;
HITCBC 707   1105 return fail(p, error::syntax, &loc); 707   1105 return fail(p, error::syntax, &loc);
708   } 708   }
709   } 709   }
710   } 710   }
HITCBC 711   8493875 return resume_value(p, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 711   8493875 return resume_value(p, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
712   } 712   }
713   713  
714   template<class Handler> 714   template<class Handler>
715   template< 715   template<
716   bool AllowComments_/*, 716   bool AllowComments_/*,
717   bool AllowTrailing_, 717   bool AllowTrailing_,
718   bool AllowBadUTF8_*/> 718   bool AllowBadUTF8_*/>
719   const char* 719   const char*
HITCBC 720   8493875 basic_parser<Handler>:: 720   8493875 basic_parser<Handler>::
721   resume_value(const char* p, 721   resume_value(const char* p,
722   std::integral_constant<bool, AllowComments_> allow_comments, 722   std::integral_constant<bool, AllowComments_> allow_comments,
723   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 723   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
724   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 724   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
725   bool allow_bad_utf16) 725   bool allow_bad_utf16)
726   { 726   {
727   state st; 727   state st;
HITCBC 728   8493875 st_.peek(st); 728   8493875 st_.peek(st);
HITCBC 729   8493875 switch(st) 729   8493875 switch(st)
730   { 730   {
731   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE 731   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE
HITCBC 732   1924 case state::lit1: 732   1924 case state::lit1:
HITCBC 733   1924 return parse_literal(p, detail::literals_c<detail::literals::resume>() ); 733   1924 return parse_literal(p, detail::literals_c<detail::literals::resume>() );
734   734  
HITCBC 735   23268 case state::str1: case state::str2: 735   23268 case state::str1: case state::str2:
736   case state::str8: 736   case state::str8:
HITCBC 737   23268 return parse_string(p, std::false_type(), std::false_type(), allow_bad_utf8, allow_bad_utf16); 737   23268 return parse_string(p, std::false_type(), std::false_type(), allow_bad_utf8, allow_bad_utf16);
738   738  
HITCBC 739   5746 case state::arr1: case state::arr2: 739   5746 case state::arr1: case state::arr2:
740   case state::arr3: case state::arr4: 740   case state::arr3: case state::arr4:
741   case state::arr5: case state::arr6: 741   case state::arr5: case state::arr6:
HITCBC 742   5746 return parse_array(p, std::false_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 742   5746 return parse_array(p, std::false_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
743   743  
HITCBC 744   35074 case state::obj1: case state::obj2: 744   35074 case state::obj1: case state::obj2:
745   case state::obj3: case state::obj4: 745   case state::obj3: case state::obj4:
746   case state::obj5: case state::obj6: 746   case state::obj5: case state::obj6:
747   case state::obj7: case state::obj8: 747   case state::obj7: case state::obj8:
748   case state::obj9: case state::obj10: 748   case state::obj9: case state::obj10:
749   case state::obj11: 749   case state::obj11:
HITCBC 750   35074 return parse_object(p, std::false_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 750   35074 return parse_object(p, std::false_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
751   751  
HITCBC 752   8426026 case state::num1: case state::num2: 752   8426026 case state::num1: case state::num2:
753   case state::num3: case state::num4: 753   case state::num3: case state::num4:
754   case state::num5: case state::num6: 754   case state::num5: case state::num6:
755   case state::num7: case state::num8: 755   case state::num7: case state::num8:
756   case state::exp1: case state::exp2: 756   case state::exp1: case state::exp2:
757   case state::exp3: 757   case state::exp3:
HITCBC 758   8426026 return mp11::mp_with_index<3>( 758   8426026 return mp11::mp_with_index<3>(
HITCBC 759   8426026 static_cast<unsigned char>(opt_.numbers), 759   8426026 static_cast<unsigned char>(opt_.numbers),
HITCBC 760   8425171 parse_number_helper<false, 0>{ this, p }); 760   8425171 parse_number_helper<false, 0>{ this, p });
761   761  
762   // KRYSTIAN NOTE: these are special cases 762   // KRYSTIAN NOTE: these are special cases
HITCBC 763   112 case state::val1: 763   112 case state::val1:
764   { 764   {
HITCBC 765   112 st_.pop(st); 765   112 st_.pop(st);
HITCBC 766   112 BOOST_ASSERT(st_.empty()); 766   112 BOOST_ASSERT(st_.empty());
HITCBC 767   112 p = detail::count_whitespace(p, end_); 767   112 p = detail::count_whitespace(p, end_);
HITCBC 768   112 if(BOOST_JSON_UNLIKELY(p == end_)) 768   112 if(BOOST_JSON_UNLIKELY(p == end_))
HITCBC 769   4 return maybe_suspend(p, state::val1); 769   4 return maybe_suspend(p, state::val1);
HITCBC 770   108 return parse_value(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 770   108 return parse_value(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
771   } 771   }
772   772  
HITCBC 773   1656 case state::val2: 773   1656 case state::val2:
774   { 774   {
HITCBC 775   1656 st_.pop(st); 775   1656 st_.pop(st);
HITCBC 776   1656 p = parse_comment(p, std::false_type(), std::false_type()); 776   1656 p = parse_comment(p, std::false_type(), std::false_type());
HITCBC 777   1636 if(BOOST_JSON_UNLIKELY(p == sentinel())) 777   1636 if(BOOST_JSON_UNLIKELY(p == sentinel()))
HITCBC 778   1314 return maybe_suspend(p, state::val2); 778   1314 return maybe_suspend(p, state::val2);
HITCBC 779   322 if(BOOST_JSON_UNLIKELY( p == end_ )) 779   322 if(BOOST_JSON_UNLIKELY( p == end_ ))
HITCBC 780   79 return maybe_suspend(p, state::val3); 780   79 return maybe_suspend(p, state::val3);
HITCBC 781   243 BOOST_ASSERT(st_.empty()); 781   243 BOOST_ASSERT(st_.empty());
HITCBC 782   243 return parse_value(p, std::true_type(), std::true_type(), allow_trailing, allow_bad_utf8, allow_bad_utf16); 782   243 return parse_value(p, std::true_type(), std::true_type(), allow_trailing, allow_bad_utf8, allow_bad_utf16);
783   } 783   }
784   784  
HITCBC 785   69 case state::val3: 785   69 case state::val3:
786   { 786   {
HITCBC 787   69 st_.pop(st); 787   69 st_.pop(st);
HITCBC 788   69 return parse_value(p, std::true_type(), std::true_type(), allow_trailing, allow_bad_utf8, allow_bad_utf16); 788   69 return parse_value(p, std::true_type(), std::true_type(), allow_trailing, allow_bad_utf8, allow_bad_utf16);
789   } 789   }
790   } 790   }
791   } 791   }
792   792  
793   template<class Handler> 793   template<class Handler>
794   template<class Literal> 794   template<class Literal>
795   const char* 795   const char*
HITCBC 796   16565 basic_parser<Handler>:: 796   16565 basic_parser<Handler>::
797   parse_literal(const char* p, Literal) 797   parse_literal(const char* p, Literal)
798   { 798   {
799   using L = detail::literals; 799   using L = detail::literals;
800   800  
801   std::size_t cur_lit; 801   std::size_t cur_lit;
802   std::size_t offset; 802   std::size_t offset;
803   803  
HITCBC 804   16565 detail::const_stream_wrapper cs(p, end_); 804   16565 detail::const_stream_wrapper cs(p, end_);
805   BOOST_IF_CONSTEXPR( Literal::value != L::resume ) 805   BOOST_IF_CONSTEXPR( Literal::value != L::resume )
806   { 806   {
HITCBC 807   13634 constexpr std::size_t index = literal_index(Literal::value); 807   13634 constexpr std::size_t index = literal_index(Literal::value);
HITCBC 808   13634 constexpr char const* literal = detail::literal_strings[index]; 808   13634 constexpr char const* literal = detail::literal_strings[index];
HITCBC 809   13634 constexpr std::size_t sz = detail::literal_sizes[index]; 809   13634 constexpr std::size_t sz = detail::literal_sizes[index];
810   810  
HITCBC 811   13634 if(BOOST_JSON_LIKELY( cs.remain() >= sz )) 811   13634 if(BOOST_JSON_LIKELY( cs.remain() >= sz ))
812   { 812   {
HITCBC 813   11984 int const cmp = std::memcmp(cs.begin(), literal, sz); 813   11984 int const cmp = std::memcmp(cs.begin(), literal, sz);
HITCBC 814   11984 if( cmp != 0 ) 814   11984 if( cmp != 0 )
815   { 815   {
816   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; 816   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
HITCBC 817   197 return fail(cs.begin(), error::syntax, &loc); 817   197 return fail(cs.begin(), error::syntax, &loc);
818   } 818   }
819   819  
820   BOOST_IF_CONSTEXPR( Literal::value == L::null ) 820   BOOST_IF_CONSTEXPR( Literal::value == L::null )
821   { 821   {
HITCBC 822   10789 if(BOOST_JSON_UNLIKELY( 822   10789 if(BOOST_JSON_UNLIKELY(
823   ! h_.on_null(ec_))) 823   ! h_.on_null(ec_)))
HITCBC 824   161 return fail(cs.begin()); 824   161 return fail(cs.begin());
825   } 825   }
826   else BOOST_IF_CONSTEXPR( Literal::value == L::true_ ) 826   else BOOST_IF_CONSTEXPR( Literal::value == L::true_ )
827   { 827   {
HITCBC 828   384 if(BOOST_JSON_UNLIKELY( 828   384 if(BOOST_JSON_UNLIKELY(
829   ! h_.on_bool(true, ec_))) 829   ! h_.on_bool(true, ec_)))
HITCBC 830   14 return fail(cs.begin()); 830   14 return fail(cs.begin());
831   } 831   }
832   else BOOST_IF_CONSTEXPR( Literal::value == L::false_ ) 832   else BOOST_IF_CONSTEXPR( Literal::value == L::false_ )
833   { 833   {
HITCBC 834   406 if(BOOST_JSON_UNLIKELY( 834   406 if(BOOST_JSON_UNLIKELY(
835   ! h_.on_bool(false, ec_))) 835   ! h_.on_bool(false, ec_)))
HITCBC 836   13 return fail(cs.begin()); 836   13 return fail(cs.begin());
837   } 837   }
838   else BOOST_IF_CONSTEXPR( Literal::value == L::infinity ) 838   else BOOST_IF_CONSTEXPR( Literal::value == L::infinity )
839   { 839   {
HITCBC 840   103 if(BOOST_JSON_UNLIKELY( 840   103 if(BOOST_JSON_UNLIKELY(
841   ! h_.on_double( 841   ! h_.on_double(
842   std::numeric_limits<double>::infinity(), 842   std::numeric_limits<double>::infinity(),
843   string_view(literal, sz), 843   string_view(literal, sz),
844   ec_))) 844   ec_)))
HITCBC 845   13 return fail(cs.begin()); 845   13 return fail(cs.begin());
846   } 846   }
847   else BOOST_IF_CONSTEXPR( Literal::value == L::neg_infinity ) 847   else BOOST_IF_CONSTEXPR( Literal::value == L::neg_infinity )
848   { 848   {
HITCBC 849   9 if(BOOST_JSON_UNLIKELY( 849   9 if(BOOST_JSON_UNLIKELY(
850   ! h_.on_double( 850   ! h_.on_double(
851   -std::numeric_limits<double>::infinity(), 851   -std::numeric_limits<double>::infinity(),
852   string_view(literal, sz), 852   string_view(literal, sz),
853   ec_))) 853   ec_)))
HITCBC 854   1 return fail(cs.begin()); 854   1 return fail(cs.begin());
855   } 855   }
856   else BOOST_IF_CONSTEXPR( Literal::value == L::nan ) 856   else BOOST_IF_CONSTEXPR( Literal::value == L::nan )
857   { 857   {
HITCBC 858   96 if(BOOST_JSON_UNLIKELY( 858   96 if(BOOST_JSON_UNLIKELY(
859   ! h_.on_double( 859   ! h_.on_double(
860   std::numeric_limits<double>::quiet_NaN(), 860   std::numeric_limits<double>::quiet_NaN(),
861   string_view(literal, sz), 861   string_view(literal, sz),
862   ec_))) 862   ec_)))
HITCBC 863   12 return fail(cs.begin()); 863   12 return fail(cs.begin());
864   } 864   }
865   else 865   else
866   { 866   {
867   BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE 867   BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE
868   } 868   }
869   869  
HITCBC 870   11363 cs += sz; 870   11363 cs += sz;
HITCBC 871   11363 return cs.begin(); 871   11363 return cs.begin();
872   } 872   }
873   873  
HITCBC 874   1650 offset = 0; 874   1650 offset = 0;
HITCBC 875   1650 cur_lit = index; 875   1650 cur_lit = index;
876   } 876   }
877   else 877   else
878   { 878   {
879   state st; 879   state st;
HITCBC 880   2931 st_.pop(st); 880   2931 st_.pop(st);
HITCBC 881   2931 BOOST_ASSERT( st == state::lit1 ); 881   2931 BOOST_ASSERT( st == state::lit1 );
882   882  
HITCBC 883   2931 cur_lit = cur_lit_; 883   2931 cur_lit = cur_lit_;
HITCBC 884   2931 offset = lit_offset_; 884   2931 offset = lit_offset_;
885   } 885   }
886   886  
HITCBC 887   4581 std::size_t const lit_size = detail::literal_sizes[cur_lit]; 887   4581 std::size_t const lit_size = detail::literal_sizes[cur_lit];
HITCBC 888   4581 std::size_t const size = (std::min)( lit_size - offset, cs.remain() ); 888   4581 std::size_t const size = (std::min)( lit_size - offset, cs.remain() );
HITCBC 889   4581 int cmp = 0; 889   4581 int cmp = 0;
HITCBC 890   4581 if(BOOST_JSON_LIKELY( cs.begin() )) 890   4581 if(BOOST_JSON_LIKELY( cs.begin() ))
HITCBC 891   4580 cmp = std::memcmp( 891   4580 cmp = std::memcmp(
HITCBC 892   4580 cs.begin(), detail::literal_strings[cur_lit] + offset, size ); 892   4580 cs.begin(), detail::literal_strings[cur_lit] + offset, size );
HITCBC 893   4581 if( cmp != 0 ) 893   4581 if( cmp != 0 )
894   { 894   {
895   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; 895   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
HITCBC 896   699 return fail(cs.begin(), error::syntax, &loc); 896   699 return fail(cs.begin(), error::syntax, &loc);
897   } 897   }
898   898  
HITCBC 899   3882 if(BOOST_JSON_UNLIKELY( offset + size < lit_size )) 899   3882 if(BOOST_JSON_UNLIKELY( offset + size < lit_size ))
900   { 900   {
HITCBC 901   1990 BOOST_ASSERT( cur_lit < 256 ); 901   1990 BOOST_ASSERT( cur_lit < 256 );
HITCBC 902   1990 cur_lit_ = static_cast<unsigned char>( cur_lit ); 902   1990 cur_lit_ = static_cast<unsigned char>( cur_lit );
HITCBC 903   1990 BOOST_ASSERT( offset + size < 256 ); 903   1990 BOOST_ASSERT( offset + size < 256 );
HITCBC 904   1990 lit_offset_ = static_cast<unsigned char>( offset + size ); 904   1990 lit_offset_ = static_cast<unsigned char>( offset + size );
HITCBC 905   1990 return maybe_suspend(cs.begin() + size, state::lit1); 905   1990 return maybe_suspend(cs.begin() + size, state::lit1);
906   } 906   }
907   907  
HITCBC 908   1892 switch( static_cast<L>(cur_lit) ) 908   1892 switch( static_cast<L>(cur_lit) )
909   { 909   {
HITCBC 910   472 case L::null: 910   472 case L::null:
HITCBC 911   472 if(BOOST_JSON_UNLIKELY( 911   472 if(BOOST_JSON_UNLIKELY(
912   ! h_.on_null(ec_))) 912   ! h_.on_null(ec_)))
HITCBC 913   61 return fail(cs.begin()); 913   61 return fail(cs.begin());
HITCBC 914   351 break; 914   351 break;
HITCBC 915   152 case L::true_: 915   152 case L::true_:
HITCBC 916   152 if(BOOST_JSON_UNLIKELY( 916   152 if(BOOST_JSON_UNLIKELY(
917   ! h_.on_bool(true, ec_))) 917   ! h_.on_bool(true, ec_)))
HITCBC 918   22 return fail(cs.begin()); 918   22 return fail(cs.begin());
HITCBC 919   109 break; 919   109 break;
HITCBC 920   198 case L::false_: 920   198 case L::false_:
HITCBC 921   198 if(BOOST_JSON_UNLIKELY( 921   198 if(BOOST_JSON_UNLIKELY(
922   ! h_.on_bool(false, ec_))) 922   ! h_.on_bool(false, ec_)))
HITCBC 923   28 return fail(cs.begin()); 923   28 return fail(cs.begin());
HITCBC 924   142 break; 924   142 break;
HITCBC 925   308 case L::infinity: 925   308 case L::infinity:
HITCBC 926   308 if(BOOST_JSON_UNLIKELY( 926   308 if(BOOST_JSON_UNLIKELY(
927   ! h_.on_double( 927   ! h_.on_double(
928   std::numeric_limits<double>::infinity(), 928   std::numeric_limits<double>::infinity(),
929   string_view( 929   string_view(
930   detail::literal_strings[ literal_index(L::infinity) ], 930   detail::literal_strings[ literal_index(L::infinity) ],
931   detail::literal_sizes[ literal_index(L::infinity) ]), 931   detail::literal_sizes[ literal_index(L::infinity) ]),
932   ec_))) 932   ec_)))
HITCBC 933   49 return fail(cs.begin()); 933   49 return fail(cs.begin());
HITCBC 934   210 break; 934   210 break;
HITCBC 935   686 case L::neg_infinity: 935   686 case L::neg_infinity:
HITCBC 936   686 if(BOOST_JSON_UNLIKELY( 936   686 if(BOOST_JSON_UNLIKELY(
937   ! h_.on_double( 937   ! h_.on_double(
938   -std::numeric_limits<double>::infinity(), 938   -std::numeric_limits<double>::infinity(),
939   string_view( 939   string_view(
940   detail::literal_strings[ literal_index(L::neg_infinity) ], 940   detail::literal_strings[ literal_index(L::neg_infinity) ],
941   detail::literal_sizes[ literal_index(L::neg_infinity) ]), 941   detail::literal_sizes[ literal_index(L::neg_infinity) ]),
942   ec_))) 942   ec_)))
HITCBC 943   102 return fail(cs.begin()); 943   102 return fail(cs.begin());
HITCBC 944   482 break; 944   482 break;
HITCBC 945   76 case L::nan: 945   76 case L::nan:
HITCBC 946   76 if(BOOST_JSON_UNLIKELY( 946   76 if(BOOST_JSON_UNLIKELY(
947   ! h_.on_double( 947   ! h_.on_double(
948   std::numeric_limits<double>::quiet_NaN(), 948   std::numeric_limits<double>::quiet_NaN(),
949   string_view( 949   string_view(
950   detail::literal_strings[ literal_index(L::nan) ], 950   detail::literal_strings[ literal_index(L::nan) ],
951   detail::literal_sizes[ literal_index(L::nan) ]), 951   detail::literal_sizes[ literal_index(L::nan) ]),
952   ec_))) 952   ec_)))
HITCBC 953   12 return fail(cs.begin()); 953   12 return fail(cs.begin());
HITCBC 954   52 break; 954   52 break;
955   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE 955   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE
956   } 956   }
957   957  
HITCBC 958   1346 cs += size; 958   1346 cs += size;
HITCBC 959   1346 return cs.begin(); 959   1346 return cs.begin();
960   } 960   }
961   961  
962   //---------------------------------------------------------- 962   //----------------------------------------------------------
963   963  
964   template<class Handler> 964   template<class Handler>
965   template<bool StackEmpty_, bool IsKey_> 965   template<bool StackEmpty_, bool IsKey_>
966   const char* 966   const char*
HITCBC 967   164348 basic_parser<Handler>:: 967   164348 basic_parser<Handler>::
968   parse_string(const char* p, 968   parse_string(const char* p,
969   std::integral_constant<bool, StackEmpty_> stack_empty, 969   std::integral_constant<bool, StackEmpty_> stack_empty,
970   std::integral_constant<bool, IsKey_> is_key, 970   std::integral_constant<bool, IsKey_> is_key,
971   bool allow_bad_utf8, 971   bool allow_bad_utf8,
972   bool allow_bad_utf16) 972   bool allow_bad_utf16)
973   { 973   {
HITCBC 974   164348 detail::const_stream_wrapper cs(p, end_); 974   164348 detail::const_stream_wrapper cs(p, end_);
975   std::size_t total; 975   std::size_t total;
976   char const* start; 976   char const* start;
977   std::size_t size; 977   std::size_t size;
HITCBC 978   164348 if(! stack_empty && ! st_.empty()) 978   164348 if(! stack_empty && ! st_.empty())
979   { 979   {
980   state st; 980   state st;
HITCBC 981   35919 st_.pop(st); 981   35919 st_.pop(st);
HITCBC 982   35919 st_.pop(total); 982   35919 st_.pop(total);
HITCBC 983   35919 switch(st) 983   35919 switch(st)
984   { 984   {
985   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE 985   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE
HITCBC 986   3149 case state::str2: goto do_str2; 986   3149 case state::str2: goto do_str2;
HITCBC 987   1868 case state::str8: goto do_str8; 987   1868 case state::str8: goto do_str8;
HITCBC 988   30902 case state::str1: break; 988   30902 case state::str1: break;
989   } 989   }
990   } 990   }
991   else 991   else
992   { 992   {
HITCBC 993   128429 BOOST_ASSERT(*cs == '\x22'); // '"' 993   128429 BOOST_ASSERT(*cs == '\x22'); // '"'
HITCBC 994   128429 ++cs; 994   128429 ++cs;
HITCBC 995   128429 total = 0; 995   128429 total = 0;
996   } 996   }
997   997  
HITCBC 998   167824 do_str1: 998   167824 do_str1:
HITCBC 999   167824 start = cs.begin(); 999   167824 start = cs.begin();
HITCBC 1000   335648 cs = allow_bad_utf8? 1000   335648 cs = allow_bad_utf8?
HITCBC 1001   2177 detail::count_valid<true>(cs.begin(), cs.end()): 1001   2177 detail::count_valid<true>(cs.begin(), cs.end()):
HITCBC 1002   165647 detail::count_valid<false>(cs.begin(), cs.end()); 1002   165647 detail::count_valid<false>(cs.begin(), cs.end());
HITCBC 1003   167824 size = cs.used(start); 1003   167824 size = cs.used(start);
HITCBC 1004   167824 if(is_key) 1004   167824 if(is_key)
1005   { 1005   {
HITCBC 1006   46712 BOOST_ASSERT(total <= Handler::max_key_size); 1006   46712 BOOST_ASSERT(total <= Handler::max_key_size);
HITCBC 1007   94023 if(BOOST_JSON_UNLIKELY(size > 1007   94023 if(BOOST_JSON_UNLIKELY(size >
1008   Handler::max_key_size - total)) 1008   Handler::max_key_size - total))
1009   { 1009   {
1010   BOOST_STATIC_CONSTEXPR source_location loc 1010   BOOST_STATIC_CONSTEXPR source_location loc
1011   = BOOST_CURRENT_LOCATION; 1011   = BOOST_CURRENT_LOCATION;
HITCBC 1012   3 return fail(cs.begin(), error::key_too_large, &loc); 1012   3 return fail(cs.begin(), error::key_too_large, &loc);
1013   } 1013   }
1014   } 1014   }
1015   else 1015   else
1016   { 1016   {
HITCBC 1017   38330 BOOST_ASSERT(total <= Handler::max_string_size); 1017   38330 BOOST_ASSERT(total <= Handler::max_string_size);
HITCBC 1018   73801 if(BOOST_JSON_UNLIKELY(size > 1018   73801 if(BOOST_JSON_UNLIKELY(size >
1019   Handler::max_string_size - total)) 1019   Handler::max_string_size - total))
1020   { 1020   {
1021   BOOST_STATIC_CONSTEXPR source_location loc 1021   BOOST_STATIC_CONSTEXPR source_location loc
1022   = BOOST_CURRENT_LOCATION; 1022   = BOOST_CURRENT_LOCATION;
HITCBC 1023   3 return fail(cs.begin(), error::string_too_large, &loc); 1023   3 return fail(cs.begin(), error::string_too_large, &loc);
1024   } 1024   }
1025   } 1025   }
HITCBC 1026   167818 total += size; 1026   167818 total += size;
HITCBC 1027   167818 if(BOOST_JSON_UNLIKELY(! cs)) 1027   167818 if(BOOST_JSON_UNLIKELY(! cs))
1028   { 1028   {
1029   // call handler if the string isn't empty 1029   // call handler if the string isn't empty
HITCBC 1030   33236 if(BOOST_JSON_LIKELY(size)) 1030   33236 if(BOOST_JSON_LIKELY(size))
1031   { 1031   {
1032   { 1032   {
HITCBC 1033   30068 bool r = is_key? 1033   30068 bool r = is_key?
HITCBC 1034   12406 h_.on_key_part( {start, size}, total, ec_ ): 1034   12406 h_.on_key_part( {start, size}, total, ec_ ):
HITCBC 1035   18996 h_.on_string_part( {start, size}, total, ec_ ); 1035   18996 h_.on_string_part( {start, size}, total, ec_ );
1036   1036  
HITCBC 1037   28960 if(BOOST_JSON_UNLIKELY(!r)) 1037   28960 if(BOOST_JSON_UNLIKELY(!r))
1038   { 1038   {
HITCBC 1039   1110 return fail(cs.begin()); 1039   1110 return fail(cs.begin());
1040   } 1040   }
1041   } 1041   }
1042   } 1042   }
HITCBC 1043   31018 return maybe_suspend(cs.begin(), state::str1, total); 1043   31018 return maybe_suspend(cs.begin(), state::str1, total);
1044   } 1044   }
1045   // at this point all valid characters have been skipped, so any remaining 1045   // at this point all valid characters have been skipped, so any remaining
1046   // if there are any more characters, they are either escaped, or incomplete 1046   // if there are any more characters, they are either escaped, or incomplete
1047   // utf8, or invalid utf8 1047   // utf8, or invalid utf8
HITCBC 1048   134582 if(BOOST_JSON_UNLIKELY(*cs != '\x22')) // '"' 1048   134582 if(BOOST_JSON_UNLIKELY(*cs != '\x22')) // '"'
1049   { 1049   {
1050   // sequence is invalid or incomplete 1050   // sequence is invalid or incomplete
HITCBC 1051   15081 if((*cs & 0x80) && !allow_bad_utf8) 1051   15081 if((*cs & 0x80) && !allow_bad_utf8)
1052   { 1052   {
HITCBC 1053   3472 seq_.save(cs.begin(), cs.remain()); 1053   3472 seq_.save(cs.begin(), cs.remain());
HITCBC 1054   3472 if(BOOST_JSON_UNLIKELY(seq_.complete())) 1054   3472 if(BOOST_JSON_UNLIKELY(seq_.complete()))
1055   { 1055   {
1056   BOOST_STATIC_CONSTEXPR source_location loc 1056   BOOST_STATIC_CONSTEXPR source_location loc
1057   = BOOST_CURRENT_LOCATION; 1057   = BOOST_CURRENT_LOCATION;
HITCBC 1058   1557 return fail(cs.begin(), error::syntax, &loc); 1058   1557 return fail(cs.begin(), error::syntax, &loc);
1059   } 1059   }
HITCBC 1060   1915 if(BOOST_JSON_LIKELY(size)) 1060   1915 if(BOOST_JSON_LIKELY(size))
1061   { 1061   {
HITCBC 1062   245 bool const r = is_key? 1062   245 bool const r = is_key?
HITCBC 1063   22 h_.on_key_part( {start, size}, total, ec_ ): 1063   22 h_.on_key_part( {start, size}, total, ec_ ):
HITCBC 1064   245 h_.on_string_part( {start, size}, total, ec_ ); 1064   245 h_.on_string_part( {start, size}, total, ec_ );
HITCBC 1065   223 if(BOOST_JSON_UNLIKELY( !r )) 1065   223 if(BOOST_JSON_UNLIKELY( !r ))
HITCBC 1066   22 return fail( cs.begin() ); 1066   22 return fail( cs.begin() );
1067   } 1067   }
HITCBC 1068   1871 return maybe_suspend(cs.end(), state::str8, total); 1068   1871 return maybe_suspend(cs.end(), state::str8, total);
1069   } 1069   }
HITCBC 1070   11609 else if(BOOST_JSON_LIKELY(*cs == '\\')) 1070   11609 else if(BOOST_JSON_LIKELY(*cs == '\\'))
1071   { 1071   {
1072   // flush unescaped run from input 1072   // flush unescaped run from input
HITCBC 1073   11500 if(BOOST_JSON_LIKELY(size)) 1073   11500 if(BOOST_JSON_LIKELY(size))
1074   { 1074   {
HITCBC 1075   4250 bool const r = is_key? 1075   4250 bool const r = is_key?
HITCBC 1076   1226 h_.on_key_part( {start, size}, total, ec_ ): 1076   1226 h_.on_key_part( {start, size}, total, ec_ ):
HITCBC 1077   3554 h_.on_string_part( {start, size}, total, ec_ ); 1077   3554 h_.on_string_part( {start, size}, total, ec_ );
HITCBC 1078   3766 if(BOOST_JSON_UNLIKELY( !r )) 1078   3766 if(BOOST_JSON_UNLIKELY( !r ))
HITCBC 1079   484 return fail( cs.begin() ); 1079   484 return fail( cs.begin() );
1080   } 1080   }
HITCBC 1081   7250 do_str2: 1081   7250 do_str2:
HITCBC 1082   13681 cs = parse_escaped(cs.begin(), total, stack_empty, is_key, allow_bad_utf16); 1082   13681 cs = parse_escaped(cs.begin(), total, stack_empty, is_key, allow_bad_utf16);
HITCBC 1083   12719 if(BOOST_JSON_UNLIKELY( incomplete(cs) )) 1083   12719 if(BOOST_JSON_UNLIKELY( incomplete(cs) ))
HITCBC 1084   5476 return suspend_or_fail(state::str2, total); 1084   5476 return suspend_or_fail(state::str2, total);
1085   1085  
HITCBC 1086   7243 goto do_str1; 1086   7243 goto do_str1;
1087   } 1087   }
1088   // illegal control 1088   // illegal control
1089   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; 1089   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
HITCBC 1090   109 return fail(cs.begin(), error::syntax, &loc); 1090   109 return fail(cs.begin(), error::syntax, &loc);
1091   } 1091   }
1092   1092  
1093   { 1093   {
HITCBC 1094   119501 bool r = is_key? 1094   119501 bool r = is_key?
HITCBC 1095   84525 h_.on_key( {start, size}, total, ec_ ): 1095   84525 h_.on_key( {start, size}, total, ec_ ):
HITCBC 1096   41985 h_.on_string( {start, size}, total, ec_ ); 1096   41985 h_.on_string( {start, size}, total, ec_ );
1097   1097  
HITCBC 1098   115127 if(BOOST_JSON_UNLIKELY(!r)) 1098   115127 if(BOOST_JSON_UNLIKELY(!r))
1099   { 1099   {
HITCBC 1100   4318 return fail(cs.begin()); 1100   4318 return fail(cs.begin());
1101   } 1101   }
1102   } 1102   }
1103   1103  
HITCBC 1104   110809 ++cs; 1104   110809 ++cs;
HITCBC 1105   110809 return cs.begin(); 1105   110809 return cs.begin();
1106   1106  
HITCBC 1107   1868 do_str8: 1107   1868 do_str8:
HITCBC 1108   1868 uint8_t needed = seq_.needed(); 1108   1868 uint8_t needed = seq_.needed();
HITCBC 1109   1868 if(BOOST_JSON_UNLIKELY( !seq_.append(cs.begin(), cs.remain()) )) 1109   1868 if(BOOST_JSON_UNLIKELY( !seq_.append(cs.begin(), cs.remain()) ))
HITCBC 1110   4 return maybe_suspend(cs.end(), state::str8, total); 1110   4 return maybe_suspend(cs.end(), state::str8, total);
HITCBC 1111   1864 if(BOOST_JSON_UNLIKELY( !seq_.valid() )) 1111   1864 if(BOOST_JSON_UNLIKELY( !seq_.valid() ))
1112   { 1112   {
1113   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; 1113   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
HITCBC 1114   210 return fail(cs.begin(), error::syntax, &loc); 1114   210 return fail(cs.begin(), error::syntax, &loc);
1115   } 1115   }
1116   { 1116   {
HITCBC 1117   1654 std::size_t const n = seq_.length(); 1117   1654 std::size_t const n = seq_.length();
1118   bool r; 1118   bool r;
HITCBC 1119   1654 if(is_key) 1119   1654 if(is_key)
1120   { 1120   {
HITCBC 1121   2 BOOST_ASSERT(total <= Handler::max_key_size); 1121   2 BOOST_ASSERT(total <= Handler::max_key_size);
HITCBC 1122   2 if(BOOST_JSON_UNLIKELY(n > 1122   2 if(BOOST_JSON_UNLIKELY(n >
1123   Handler::max_key_size - total)) 1123   Handler::max_key_size - total))
1124   { 1124   {
1125   BOOST_STATIC_CONSTEXPR source_location loc 1125   BOOST_STATIC_CONSTEXPR source_location loc
1126   = BOOST_CURRENT_LOCATION; 1126   = BOOST_CURRENT_LOCATION;
HITCBC 1127   1 return fail(cs.begin(), error::key_too_large, &loc); 1127   1 return fail(cs.begin(), error::key_too_large, &loc);
1128   } 1128   }
HITCBC 1129   1 total += n; 1129   1 total += n;
HITCBC 1130   1 r = h_.on_key_part( {seq_.data(), n}, total, ec_ ); 1130   1 r = h_.on_key_part( {seq_.data(), n}, total, ec_ );
1131   } 1131   }
1132   else 1132   else
1133   { 1133   {
HITCBC 1134   1 BOOST_ASSERT(total <= Handler::max_string_size); 1134   1 BOOST_ASSERT(total <= Handler::max_string_size);
HITCBC 1135   1652 if(BOOST_JSON_UNLIKELY(n > 1135   1652 if(BOOST_JSON_UNLIKELY(n >
1136   Handler::max_string_size - total)) 1136   Handler::max_string_size - total))
1137   { 1137   {
1138   BOOST_STATIC_CONSTEXPR source_location loc 1138   BOOST_STATIC_CONSTEXPR source_location loc
1139   = BOOST_CURRENT_LOCATION; 1139   = BOOST_CURRENT_LOCATION;
HITCBC 1140   1 return fail(cs.begin(), error::string_too_large, &loc); 1140   1 return fail(cs.begin(), error::string_too_large, &loc);
1141   } 1141   }
HITCBC 1142   1651 total += n; 1142   1651 total += n;
HITCBC 1143   1651 r = h_.on_string_part( {seq_.data(), n}, total, ec_ ); 1143   1651 r = h_.on_string_part( {seq_.data(), n}, total, ec_ );
1144   } 1144   }
HITCBC 1145   1451 if(BOOST_JSON_UNLIKELY( !r )) 1145   1451 if(BOOST_JSON_UNLIKELY( !r ))
HITCBC 1146   201 return fail( cs.begin() ); 1146   201 return fail( cs.begin() );
1147   } 1147   }
HITCBC 1148   1250 cs += needed; 1148   1250 cs += needed;
HITCBC 1149   1250 goto do_str1; 1149   1250 goto do_str1;
1150   } 1150   }
1151   1151  
1152   template<class Handler> 1152   template<class Handler>
1153   template<bool StackEmpty_> 1153   template<bool StackEmpty_>
1154   const char* 1154   const char*
HITCBC 1155   13681 basic_parser<Handler>:: 1155   13681 basic_parser<Handler>::
1156   parse_escaped( 1156   parse_escaped(
1157   const char* p, 1157   const char* p,
1158   std::size_t& total, 1158   std::size_t& total,
1159   std::integral_constant<bool, StackEmpty_> stack_empty, 1159   std::integral_constant<bool, StackEmpty_> stack_empty,
1160   bool is_key, 1160   bool is_key,
1161   bool allow_bad_utf16) 1161   bool allow_bad_utf16)
1162   { 1162   {
HITCBC 1163   13681 constexpr unsigned urc = 0xFFFD; // Unicode replacement character 1163   13681 constexpr unsigned urc = 0xFFFD; // Unicode replacement character
HITCBC 1164   13681 auto const ev_too_large = is_key? 1164   13681 auto const ev_too_large = is_key?
1165   error::key_too_large : error::string_too_large; 1165   error::key_too_large : error::string_too_large;
HITCBC 1166   13681 auto const max_size = is_key? 1166   13681 auto const max_size = is_key?
1167   Handler::max_key_size : Handler::max_string_size; 1167   Handler::max_key_size : Handler::max_string_size;
1168   int digit; 1168   int digit;
1169   1169  
1170   //--------------------------------------------------------------- 1170   //---------------------------------------------------------------
1171   // 1171   //
1172   // To handle escapes, a local temporary buffer accumulates 1172   // To handle escapes, a local temporary buffer accumulates
1173   // the unescaped result. The algorithm attempts to fill the 1173   // the unescaped result. The algorithm attempts to fill the
1174   // buffer to capacity before invoking the handler. 1174   // buffer to capacity before invoking the handler.
1175   // In some cases the temporary buffer needs to be flushed 1175   // In some cases the temporary buffer needs to be flushed
1176   // before it is full: 1176   // before it is full:
1177   // * When the closing double quote is seen 1177   // * When the closing double quote is seen
1178   // * When there in no more input (and more is expected later) 1178   // * When there in no more input (and more is expected later)
1179   // A goal of the algorithm is to call the handler as few times 1179   // A goal of the algorithm is to call the handler as few times
1180   // as possible. Thus, when the first escape is encountered, 1180   // as possible. Thus, when the first escape is encountered,
1181   // the algorithm attempts to fill the temporary buffer first. 1181   // the algorithm attempts to fill the temporary buffer first.
1182   // 1182   //
HITCBC 1183   13681 detail::buffer<BOOST_JSON_STACK_BUFFER_SIZE> temp; 1183   13681 detail::buffer<BOOST_JSON_STACK_BUFFER_SIZE> temp;
1184   1184  
1185   // Unescaped JSON is never larger than its escaped version. 1185   // Unescaped JSON is never larger than its escaped version.
1186   // To efficiently process only what will fit in the temporary buffer, 1186   // To efficiently process only what will fit in the temporary buffer,
1187   // the size of the input stream is temporarily "clipped" to the size 1187   // the size of the input stream is temporarily "clipped" to the size
1188   // of the temporary buffer. 1188   // of the temporary buffer.
1189   // handle escaped character 1189   // handle escaped character
HITCBC 1190   13681 detail::clipped_const_stream cs(p, end_); 1190   13681 detail::clipped_const_stream cs(p, end_);
HITCBC 1191   13681 cs.clip(temp.max_size()); 1191   13681 cs.clip(temp.max_size());
1192   1192  
HITCBC 1193   13681 if(! stack_empty && ! st_.empty()) 1193   13681 if(! stack_empty && ! st_.empty())
1194   { 1194   {
1195   state st; 1195   state st;
HITCBC 1196   3149 st_.pop(st); 1196   3149 st_.pop(st);
HITCBC 1197   3149 switch(st) 1197   3149 switch(st)
1198   { 1198   {
1199   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE 1199   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE
HITCBC 1200   528 case state::str3: goto do_str3; 1200   528 case state::str3: goto do_str3;
HITCBC 1201   392 case state::str4: goto do_str4; 1201   392 case state::str4: goto do_str4;
HITCBC 1202   390 case state::str5: goto do_str5; 1202   390 case state::str5: goto do_str5;
HITCBC 1203   389 case state::str6: goto do_str6; 1203   389 case state::str6: goto do_str6;
HITCBC 1204   386 case state::str7: goto do_str7; 1204   386 case state::str7: goto do_str7;
HITCBC 1205   232 case state::sur1: goto do_sur1; 1205   232 case state::sur1: goto do_sur1;
HITCBC 1206   188 case state::sur2: goto do_sur2; 1206   188 case state::sur2: goto do_sur2;
HITCBC 1207   164 case state::sur3: goto do_sur3; 1207   164 case state::sur3: goto do_sur3;
HITCBC 1208   162 case state::sur4: goto do_sur4; 1208   162 case state::sur4: goto do_sur4;
HITCBC 1209   160 case state::sur5: goto do_sur5; 1209   160 case state::sur5: goto do_sur5;
HITCBC 1210   158 case state::sur6: goto do_sur6; 1210   158 case state::sur6: goto do_sur6;
1211   } 1211   }
1212   } 1212   }
1213   1213  
HITCBC 1214   3783 while(true) 1214   3783 while(true)
1215   { 1215   {
HITCBC 1216   14315 BOOST_ASSERT( temp.capacity() ); 1216   14315 BOOST_ASSERT( temp.capacity() );
HITCBC 1217   14315 BOOST_ASSERT(*cs == '\\'); 1217   14315 BOOST_ASSERT(*cs == '\\');
HITCBC 1218   14315 ++cs; 1218   14315 ++cs;
HITCBC 1219   15174 do_str3: 1219   15174 do_str3:
HITCBC 1220   15379 if(BOOST_JSON_UNLIKELY(! cs)) 1220   15379 if(BOOST_JSON_UNLIKELY(! cs))
1221   { 1221   {
HITCBC 1222   562 if(BOOST_JSON_LIKELY(! temp.empty())) 1222   562 if(BOOST_JSON_LIKELY(! temp.empty()))
1223   { 1223   {
HITCBC 1224   1 BOOST_ASSERT(total <= max_size); 1224   1 BOOST_ASSERT(total <= max_size);
HITCBC 1225   101 if(BOOST_JSON_UNLIKELY( 1225   101 if(BOOST_JSON_UNLIKELY(
1226   temp.size() > max_size - total)) 1226   temp.size() > max_size - total))
1227   { 1227   {
1228   BOOST_STATIC_CONSTEXPR source_location loc 1228   BOOST_STATIC_CONSTEXPR source_location loc
1229   = BOOST_CURRENT_LOCATION; 1229   = BOOST_CURRENT_LOCATION;
HITCBC 1230   1 return fail(cs.begin(), ev_too_large, &loc); 1230   1 return fail(cs.begin(), ev_too_large, &loc);
1231   } 1231   }
HITCBC 1232   100 total += temp.size(); 1232   100 total += temp.size();
1233   { 1233   {
HITCBC 1234   91 bool r = is_key 1234   91 bool r = is_key
HITCBC 1235   100 ? h_.on_key_part(temp.get(), total, ec_) 1235   100 ? h_.on_key_part(temp.get(), total, ec_)
HITCBC 1236   100 : h_.on_string_part(temp.get(), total, ec_); 1236   100 : h_.on_string_part(temp.get(), total, ec_);
1237   1237  
HITCBC 1238   91 if(BOOST_JSON_UNLIKELY(!r)) 1238   91 if(BOOST_JSON_UNLIKELY(!r))
1239   { 1239   {
HITCBC 1240   9 return fail(cs.begin()); 1240   9 return fail(cs.begin());
1241   } 1241   }
1242   } 1242   }
HITCBC 1243   82 temp.clear(); 1243   82 temp.clear();
1244   } 1244   }
HITCBC 1245   543 cs.clip(temp.max_size()); 1245   543 cs.clip(temp.max_size());
HITCBC 1246   543 if(BOOST_JSON_UNLIKELY(! cs)) 1246   543 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1247   543 return maybe_suspend(cs.begin(), state::str3); 1247   543 return maybe_suspend(cs.begin(), state::str3);
1248   } 1248   }
HITCBC 1249   14817 switch(*cs) 1249   14817 switch(*cs)
1250   { 1250   {
HITCBC 1251   191 default: 1251   191 default:
1252   { 1252   {
1253   BOOST_STATIC_CONSTEXPR source_location loc 1253   BOOST_STATIC_CONSTEXPR source_location loc
1254   = BOOST_CURRENT_LOCATION; 1254   = BOOST_CURRENT_LOCATION;
HITCBC 1255   191 return fail(cs.begin(), error::syntax, &loc); 1255   191 return fail(cs.begin(), error::syntax, &loc);
1256   } 1256   }
HITCBC 1257   265 case '\x22': // '"' 1257   265 case '\x22': // '"'
HITCBC 1258   265 temp.push_back('\x22'); 1258   265 temp.push_back('\x22');
HITCBC 1259   265 ++cs; 1259   265 ++cs;
HITCBC 1260   265 break; 1260   265 break;
HITCBC 1261   178 case '\\': 1261   178 case '\\':
HITCBC 1262   178 temp.push_back('\\'); 1262   178 temp.push_back('\\');
HITCBC 1263   178 ++cs; 1263   178 ++cs;
HITCBC 1264   178 break; 1264   178 break;
HITCBC 1265   96 case '/': 1265   96 case '/':
HITCBC 1266   96 temp.push_back('/'); 1266   96 temp.push_back('/');
HITCBC 1267   96 ++cs; 1267   96 ++cs;
HITCBC 1268   96 break; 1268   96 break;
HITCBC 1269   112 case 'b': 1269   112 case 'b':
HITCBC 1270   112 temp.push_back('\x08'); 1270   112 temp.push_back('\x08');
HITCBC 1271   112 ++cs; 1271   112 ++cs;
HITCBC 1272   112 break; 1272   112 break;
HITCBC 1273   108 case 'f': 1273   108 case 'f':
HITCBC 1274   108 temp.push_back('\x0c'); 1274   108 temp.push_back('\x0c');
HITCBC 1275   108 ++cs; 1275   108 ++cs;
HITCBC 1276   108 break; 1276   108 break;
HITCBC 1277   1766 case 'n': 1277   1766 case 'n':
HITCBC 1278   1766 temp.push_back('\x0a'); 1278   1766 temp.push_back('\x0a');
HITCBC 1279   1766 ++cs; 1279   1766 ++cs;
HITCBC 1280   1766 break; 1280   1766 break;
HITCBC 1281   146 case 'r': 1281   146 case 'r':
HITCBC 1282   146 temp.push_back('\x0d'); 1282   146 temp.push_back('\x0d');
HITCBC 1283   146 ++cs; 1283   146 ++cs;
HITCBC 1284   146 break; 1284   146 break;
HITCBC 1285   266 case 't': 1285   266 case 't':
HITCBC 1286   266 temp.push_back('\x09'); 1286   266 temp.push_back('\x09');
HITCBC 1287   266 ++cs; 1287   266 ++cs;
HITCBC 1288   266 break; 1288   266 break;
HITCBC 1289   11689 case 'u': 1289   11689 case 'u':
1290   // utf16 escape 1290   // utf16 escape
1291   // 1291   //
1292   // fast path only when the buffer 1292   // fast path only when the buffer
1293   // is large enough for 2 surrogates 1293   // is large enough for 2 surrogates
HITCBC 1294   11689 if(BOOST_JSON_LIKELY(cs.remain() > 10)) 1294   11689 if(BOOST_JSON_LIKELY(cs.remain() > 10))
1295   { 1295   {
1296   // KRYSTIAN TODO: this could be done 1296   // KRYSTIAN TODO: this could be done
1297   // with fewer instructions 1297   // with fewer instructions
HITCBC 1298   11394 digit = detail::load_little_endian<4>( 1298   11394 digit = detail::load_little_endian<4>(
HITCBC 1299   5697 cs.begin() + 1); 1299   5697 cs.begin() + 1);
HITCBC 1300   5697 int d4 = detail::hex_digit(static_cast< 1300   5697 int d4 = detail::hex_digit(static_cast<
HITCBC 1301   5697 unsigned char>(digit >> 24)); 1301   5697 unsigned char>(digit >> 24));
HITCBC 1302   5697 int d3 = detail::hex_digit(static_cast< 1302   5697 int d3 = detail::hex_digit(static_cast<
HITCBC 1303   5697 unsigned char>(digit >> 16)); 1303   5697 unsigned char>(digit >> 16));
HITCBC 1304   5697 int d2 = detail::hex_digit(static_cast< 1304   5697 int d2 = detail::hex_digit(static_cast<
HITCBC 1305   5697 unsigned char>(digit >> 8)); 1305   5697 unsigned char>(digit >> 8));
HITCBC 1306   5697 int d1 = detail::hex_digit(static_cast< 1306   5697 int d1 = detail::hex_digit(static_cast<
1307   unsigned char>(digit)); 1307   unsigned char>(digit));
HITCBC 1308   5697 if(BOOST_JSON_UNLIKELY( 1308   5697 if(BOOST_JSON_UNLIKELY(
1309   (d1 | d2 | d3 | d4) == -1)) 1309   (d1 | d2 | d3 | d4) == -1))
1310   { 1310   {
HITCBC 1311   60 if(d1 != -1) 1311   60 if(d1 != -1)
HITCBC 1312   45 ++cs; 1312   45 ++cs;
HITCBC 1313   60 if(d2 != -1) 1313   60 if(d2 != -1)
HITCBC 1314   30 ++cs; 1314   30 ++cs;
HITCBC 1315   60 if(d3 != -1) 1315   60 if(d3 != -1)
HITCBC 1316   15 ++cs; 1316   15 ++cs;
1317   BOOST_STATIC_CONSTEXPR source_location loc 1317   BOOST_STATIC_CONSTEXPR source_location loc
1318   = BOOST_CURRENT_LOCATION; 1318   = BOOST_CURRENT_LOCATION;
HITCBC 1319   60 return fail(cs.begin(), error::expected_hex_digit, &loc); 1319   60 return fail(cs.begin(), error::expected_hex_digit, &loc);
1320   } 1320   }
1321   // 32 bit unicode scalar value 1321   // 32 bit unicode scalar value
HITCBC 1322   5637 unsigned u1 = 1322   5637 unsigned u1 =
HITCBC 1323   5637 (d1 << 12) + (d2 << 8) + 1323   5637 (d1 << 12) + (d2 << 8) +
HITCBC 1324   5637 (d3 << 4) + d4; 1324   5637 (d3 << 4) + d4;
1325   // valid unicode scalar values are 1325   // valid unicode scalar values are
1326   // [0, D7FF] and [E000, 10FFFF] 1326   // [0, D7FF] and [E000, 10FFFF]
1327   // values within this range are valid utf-8 1327   // values within this range are valid utf-8
1328   // code points and invalid leading surrogates. 1328   // code points and invalid leading surrogates.
HITCBC 1329   5637 if(BOOST_JSON_LIKELY( 1329   5637 if(BOOST_JSON_LIKELY(
1330   u1 < 0xd800 || u1 > 0xdfff)) 1330   u1 < 0xd800 || u1 > 0xdfff))
1331   { 1331   {
HITCBC 1332   1340 cs += 5; 1332   1340 cs += 5;
HITCBC 1333   1340 temp.append_utf8(u1); 1333   1340 temp.append_utf8(u1);
HITCBC 1334   1340 break; 1334   1340 break;
1335   } 1335   }
HITCBC 1336   4297 if(BOOST_JSON_UNLIKELY(u1 > 0xdbff)) 1336   4297 if(BOOST_JSON_UNLIKELY(u1 > 0xdbff))
1337   { 1337   {
1338   // If it's an illegal leading surrogate and 1338   // If it's an illegal leading surrogate and
1339   // the parser does not allow it, return an error. 1339   // the parser does not allow it, return an error.
HITCBC 1340   707 if(!allow_bad_utf16) 1340   707 if(!allow_bad_utf16)
1341   { 1341   {
1342   BOOST_STATIC_CONSTEXPR source_location loc 1342   BOOST_STATIC_CONSTEXPR source_location loc
1343   = BOOST_CURRENT_LOCATION; 1343   = BOOST_CURRENT_LOCATION;
HITCBC 1344   122 return fail(cs.begin(), error::illegal_leading_surrogate, 1344   122 return fail(cs.begin(), error::illegal_leading_surrogate,
HITCBC 1345   122 &loc); 1345   122 &loc);
1346   } 1346   }
1347   // Otherwise, append the Unicode replacement character 1347   // Otherwise, append the Unicode replacement character
1348   else 1348   else
1349   { 1349   {
HITCBC 1350   585 cs += 5; 1350   585 cs += 5;
HITCBC 1351   585 temp.append_utf8(urc); 1351   585 temp.append_utf8(urc);
HITCBC 1352   585 break; 1352   585 break;
1353   } 1353   }
1354   } 1354   }
HITCBC 1355   3590 cs += 5; 1355   3590 cs += 5;
1356   // KRYSTIAN TODO: this can be a two byte load 1356   // KRYSTIAN TODO: this can be a two byte load
1357   // and a single comparison. We lose error information, 1357   // and a single comparison. We lose error information,
1358   // but it's faster. 1358   // but it's faster.
HITCBC 1359   3590 if(BOOST_JSON_UNLIKELY(*cs != '\\')) 1359   3590 if(BOOST_JSON_UNLIKELY(*cs != '\\'))
1360   { 1360   {
1361   // If the next character is not a backslash and 1361   // If the next character is not a backslash and
1362   // the parser does not allow it, return a syntax error. 1362   // the parser does not allow it, return a syntax error.
HITCBC 1363   156 if(!allow_bad_utf16) 1363   156 if(!allow_bad_utf16)
1364   { 1364   {
1365   BOOST_STATIC_CONSTEXPR source_location loc 1365   BOOST_STATIC_CONSTEXPR source_location loc
1366   = BOOST_CURRENT_LOCATION; 1366   = BOOST_CURRENT_LOCATION;
HITCBC 1367   15 return fail(cs.begin(), error::syntax, &loc); 1367   15 return fail(cs.begin(), error::syntax, &loc);
1368   } 1368   }
1369   // Otherwise, append the Unicode replacement character since 1369   // Otherwise, append the Unicode replacement character since
1370   // the first code point is a valid leading surrogate 1370   // the first code point is a valid leading surrogate
1371   else 1371   else
1372   { 1372   {
HITCBC 1373   141 temp.append_utf8(urc); 1373   141 temp.append_utf8(urc);
HITCBC 1374   141 break; 1374   141 break;
1375   } 1375   }
1376   } 1376   }
HITCBC 1377   3434 ++cs; 1377   3434 ++cs;
HITCBC 1378   3434 if(BOOST_JSON_UNLIKELY(*cs != 'u')) 1378   3434 if(BOOST_JSON_UNLIKELY(*cs != 'u'))
1379   { 1379   {
HITCBC 1380   220 if (!allow_bad_utf16) 1380   220 if (!allow_bad_utf16)
1381   { 1381   {
1382   BOOST_STATIC_CONSTEXPR source_location loc 1382   BOOST_STATIC_CONSTEXPR source_location loc
1383   = BOOST_CURRENT_LOCATION; 1383   = BOOST_CURRENT_LOCATION;
HITCBC 1384   15 return fail(cs.begin(), error::syntax, &loc); 1384   15 return fail(cs.begin(), error::syntax, &loc);
1385   } 1385   }
1386   // Otherwise, append the Unicode replacement character since 1386   // Otherwise, append the Unicode replacement character since
1387   // the first code point is a valid leading surrogate 1387   // the first code point is a valid leading surrogate
1388   else 1388   else
1389   { 1389   {
HITCBC 1390   205 temp.append_utf8(urc); 1390   205 temp.append_utf8(urc);
HITCBC 1391   205 goto do_str3; 1391   205 goto do_str3;
1392   } 1392   }
1393   } 1393   }
HITCBC 1394   3214 ++cs; 1394   3214 ++cs;
HITCBC 1395   3214 digit = detail::load_little_endian<4>(cs.begin()); 1395   3214 digit = detail::load_little_endian<4>(cs.begin());
HITCBC 1396   3214 d4 = detail::hex_digit(static_cast< 1396   3214 d4 = detail::hex_digit(static_cast<
HITCBC 1397   3214 unsigned char>(digit >> 24)); 1397   3214 unsigned char>(digit >> 24));
HITCBC 1398   3214 d3 = detail::hex_digit(static_cast< 1398   3214 d3 = detail::hex_digit(static_cast<
HITCBC 1399   3214 unsigned char>(digit >> 16)); 1399   3214 unsigned char>(digit >> 16));
HITCBC 1400   3214 d2 = detail::hex_digit(static_cast< 1400   3214 d2 = detail::hex_digit(static_cast<
HITCBC 1401   3214 unsigned char>(digit >> 8)); 1401   3214 unsigned char>(digit >> 8));
HITCBC 1402   3214 d1 = detail::hex_digit(static_cast< 1402   3214 d1 = detail::hex_digit(static_cast<
1403   unsigned char>(digit)); 1403   unsigned char>(digit));
HITCBC 1404   3214 if(BOOST_JSON_UNLIKELY( 1404   3214 if(BOOST_JSON_UNLIKELY(
1405   (d1 | d2 | d3 | d4) == -1)) 1405   (d1 | d2 | d3 | d4) == -1))
1406   { 1406   {
HITCBC 1407   90 if(d1 != -1) 1407   90 if(d1 != -1)
HITCBC 1408   75 ++cs; 1408   75 ++cs;
HITCBC 1409   90 if(d2 != -1) 1409   90 if(d2 != -1)
HITCBC 1410   45 ++cs; 1410   45 ++cs;
HITCBC 1411   90 if(d3 != -1) 1411   90 if(d3 != -1)
HITCBC 1412   15 ++cs; 1412   15 ++cs;
1413   BOOST_STATIC_CONSTEXPR source_location loc 1413   BOOST_STATIC_CONSTEXPR source_location loc
1414   = BOOST_CURRENT_LOCATION; 1414   = BOOST_CURRENT_LOCATION;
HITCBC 1415   90 return fail(cs.begin(), error::expected_hex_digit, &loc); 1415   90 return fail(cs.begin(), error::expected_hex_digit, &loc);
1416   } 1416   }
HITCBC 1417   3124 unsigned u2 = 1417   3124 unsigned u2 =
HITCBC 1418   3124 (d1 << 12) + (d2 << 8) + 1418   3124 (d1 << 12) + (d2 << 8) +
HITCBC 1419   3124 (d3 << 4) + d4; 1419   3124 (d3 << 4) + d4;
1420   // Check if the second code point is a valid trailing surrogate. 1420   // Check if the second code point is a valid trailing surrogate.
1421   // Valid trailing surrogates are [DC00, DFFF] 1421   // Valid trailing surrogates are [DC00, DFFF]
HITCBC 1422   3124 if(BOOST_JSON_UNLIKELY( 1422   3124 if(BOOST_JSON_UNLIKELY(
1423   u2 < 0xdc00 || u2 > 0xdfff)) 1423   u2 < 0xdc00 || u2 > 0xdfff))
1424   { 1424   {
1425   // If not valid and the parser does not allow it, return an error. 1425   // If not valid and the parser does not allow it, return an error.
HITCBC 1426   1353 if(!allow_bad_utf16) 1426   1353 if(!allow_bad_utf16)
1427   { 1427   {
1428   BOOST_STATIC_CONSTEXPR source_location loc 1428   BOOST_STATIC_CONSTEXPR source_location loc
1429   = BOOST_CURRENT_LOCATION; 1429   = BOOST_CURRENT_LOCATION;
HITCBC 1430   136 return fail(cs.begin(), error::illegal_trailing_surrogate, 1430   136 return fail(cs.begin(), error::illegal_trailing_surrogate,
HITCBC 1431   136 &loc); 1431   136 &loc);
1432   } 1432   }
1433   // Append the replacement character for the 1433   // Append the replacement character for the
1434   // first leading surrogate. 1434   // first leading surrogate.
HITCBC 1435   1217 cs += 4; 1435   1217 cs += 4;
HITCBC 1436   1217 temp.append_utf8(urc); 1436   1217 temp.append_utf8(urc);
1437   // Check if the second code point is a 1437   // Check if the second code point is a
1438   // valid unicode scalar value (invalid leading 1438   // valid unicode scalar value (invalid leading
1439   // or trailing surrogate) 1439   // or trailing surrogate)
HITCBC 1440   1217 if (u2 < 0xd800 || u2 > 0xdbff) 1440   1217 if (u2 < 0xd800 || u2 > 0xdbff)
1441   { 1441   {
HITCBC 1442   524 temp.append_utf8(u2); 1442   524 temp.append_utf8(u2);
HITCBC 1443   524 break; 1443   524 break;
1444   } 1444   }
1445   // If it is a valid leading surrogate 1445   // If it is a valid leading surrogate
1446   else 1446   else
1447   { 1447   {
HITCBC 1448   693 u1_ = u2; 1448   693 u1_ = u2;
HITCBC 1449   693 goto do_sur1; 1449   693 goto do_sur1;
1450   } 1450   }
1451   } 1451   }
HITCBC 1452   1771 cs += 4; 1452   1771 cs += 4;
1453   // Calculate the Unicode code point from the surrogate pair and 1453   // Calculate the Unicode code point from the surrogate pair and
1454   // append the UTF-8 representation. 1454   // append the UTF-8 representation.
HITCBC 1455   1771 unsigned cp = 1455   1771 unsigned cp =
HITCBC 1456   1771 ((u1 - 0xd800) << 10) + 1456   1771 ((u1 - 0xd800) << 10) +
1457   ((u2 - 0xdc00)) + 1457   ((u2 - 0xdc00)) +
1458   0x10000; 1458   0x10000;
1459   // utf-16 surrogate pair 1459   // utf-16 surrogate pair
HITCBC 1460   1771 temp.append_utf8(cp); 1460   1771 temp.append_utf8(cp);
HITCBC 1461   1771 break; 1461   1771 break;
1462   } 1462   }
1463   // flush 1463   // flush
HITCBC 1464   5992 if(BOOST_JSON_LIKELY(! temp.empty())) 1464   5992 if(BOOST_JSON_LIKELY(! temp.empty()))
1465   { 1465   {
HITCBC 1466   4 BOOST_ASSERT(total <= max_size); 1466   4 BOOST_ASSERT(total <= max_size);
HITCBC 1467   1723 if(BOOST_JSON_UNLIKELY( 1467   1723 if(BOOST_JSON_UNLIKELY(
1468   temp.size() > max_size - total)) 1468   temp.size() > max_size - total))
1469   { 1469   {
1470   BOOST_STATIC_CONSTEXPR source_location loc 1470   BOOST_STATIC_CONSTEXPR source_location loc
1471   = BOOST_CURRENT_LOCATION; 1471   = BOOST_CURRENT_LOCATION;
HITCBC 1472   1 return fail(cs.begin(), ev_too_large, &loc); 1472   1 return fail(cs.begin(), ev_too_large, &loc);
1473   } 1473   }
HITCBC 1474   1722 total += temp.size(); 1474   1722 total += temp.size();
1475   { 1475   {
HITCBC 1476   1582 bool r = is_key 1476   1582 bool r = is_key
HITCBC 1477   1722 ? h_.on_key_part(temp.get(), total, ec_) 1477   1722 ? h_.on_key_part(temp.get(), total, ec_)
HITCBC 1478   1722 : h_.on_string_part(temp.get(), total, ec_); 1478   1722 : h_.on_string_part(temp.get(), total, ec_);
1479   1479  
HITCBC 1480   1582 if(BOOST_JSON_UNLIKELY(!r)) 1480   1582 if(BOOST_JSON_UNLIKELY(!r))
1481   { 1481   {
HITCBC 1482   140 return fail(cs.begin()); 1482   140 return fail(cs.begin());
1483   } 1483   }
1484   } 1484   }
HITCBC 1485   1442 temp.clear(); 1485   1442 temp.clear();
HITCBC 1486   1442 cs.clip(temp.max_size()); 1486   1442 cs.clip(temp.max_size());
1487   } 1487   }
HITCBC 1488   5711 ++cs; 1488   5711 ++cs;
1489   // utf-16 escape 1489   // utf-16 escape
HITCBC 1490   6103 do_str4: 1490   6103 do_str4:
HITCBC 1491   6103 if(BOOST_JSON_UNLIKELY(! cs)) 1491   6103 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1492   392 return maybe_suspend(cs.begin(), state::str4); 1492   392 return maybe_suspend(cs.begin(), state::str4);
HITCBC 1493   5711 digit = detail::hex_digit(*cs); 1493   5711 digit = detail::hex_digit(*cs);
HITCBC 1494   5711 if(BOOST_JSON_UNLIKELY(digit == -1)) 1494   5711 if(BOOST_JSON_UNLIKELY(digit == -1))
1495   { 1495   {
1496   BOOST_STATIC_CONSTEXPR source_location loc 1496   BOOST_STATIC_CONSTEXPR source_location loc
1497   = BOOST_CURRENT_LOCATION; 1497   = BOOST_CURRENT_LOCATION;
HITCBC 1498   50 return fail(cs.begin(), error::expected_hex_digit, &loc); 1498   50 return fail(cs.begin(), error::expected_hex_digit, &loc);
1499   } 1499   }
HITCBC 1500   5661 ++cs; 1500   5661 ++cs;
HITCBC 1501   5661 u1_ = digit << 12; 1501   5661 u1_ = digit << 12;
HITCBC 1502   6051 do_str5: 1502   6051 do_str5:
HITCBC 1503   6051 if(BOOST_JSON_UNLIKELY(! cs)) 1503   6051 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1504   390 return maybe_suspend(cs.begin(), state::str5); 1504   390 return maybe_suspend(cs.begin(), state::str5);
HITCBC 1505   5661 digit = detail::hex_digit(*cs); 1505   5661 digit = detail::hex_digit(*cs);
HITCBC 1506   5661 if(BOOST_JSON_UNLIKELY(digit == -1)) 1506   5661 if(BOOST_JSON_UNLIKELY(digit == -1))
1507   { 1507   {
1508   BOOST_STATIC_CONSTEXPR source_location loc 1508   BOOST_STATIC_CONSTEXPR source_location loc
1509   = BOOST_CURRENT_LOCATION; 1509   = BOOST_CURRENT_LOCATION;
HITCBC 1510   20 return fail(cs.begin(), error::expected_hex_digit, &loc); 1510   20 return fail(cs.begin(), error::expected_hex_digit, &loc);
1511   } 1511   }
HITCBC 1512   5641 ++cs; 1512   5641 ++cs;
HITCBC 1513   5641 u1_ += digit << 8; 1513   5641 u1_ += digit << 8;
HITCBC 1514   6030 do_str6: 1514   6030 do_str6:
HITCBC 1515   6030 if(BOOST_JSON_UNLIKELY(! cs)) 1515   6030 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1516   389 return maybe_suspend(cs.begin(), state::str6); 1516   389 return maybe_suspend(cs.begin(), state::str6);
HITCBC 1517   5641 digit = detail::hex_digit(*cs); 1517   5641 digit = detail::hex_digit(*cs);
HITCBC 1518   5641 if(BOOST_JSON_UNLIKELY(digit == -1)) 1518   5641 if(BOOST_JSON_UNLIKELY(digit == -1))
1519   { 1519   {
1520   BOOST_STATIC_CONSTEXPR source_location loc 1520   BOOST_STATIC_CONSTEXPR source_location loc
1521   = BOOST_CURRENT_LOCATION; 1521   = BOOST_CURRENT_LOCATION;
HITCBC 1522   20 return fail(cs.begin(), error::expected_hex_digit, &loc); 1522   20 return fail(cs.begin(), error::expected_hex_digit, &loc);
1523   } 1523   }
HITCBC 1524   5621 ++cs; 1524   5621 ++cs;
HITCBC 1525   5621 u1_ += digit << 4; 1525   5621 u1_ += digit << 4;
HITCBC 1526   6007 do_str7: 1526   6007 do_str7:
HITCBC 1527   6007 if(BOOST_JSON_UNLIKELY(! cs)) 1527   6007 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1528   386 return maybe_suspend(cs.begin(), state::str7); 1528   386 return maybe_suspend(cs.begin(), state::str7);
HITCBC 1529   5621 digit = detail::hex_digit(*cs); 1529   5621 digit = detail::hex_digit(*cs);
HITCBC 1530   5621 if(BOOST_JSON_UNLIKELY(digit == -1)) 1530   5621 if(BOOST_JSON_UNLIKELY(digit == -1))
1531   { 1531   {
1532   BOOST_STATIC_CONSTEXPR source_location loc 1532   BOOST_STATIC_CONSTEXPR source_location loc
1533   = BOOST_CURRENT_LOCATION; 1533   = BOOST_CURRENT_LOCATION;
HITCBC 1534   35 return fail(cs.begin(), error::expected_hex_digit, &loc); 1534   35 return fail(cs.begin(), error::expected_hex_digit, &loc);
1535   } 1535   }
HITCBC 1536   5586 ++cs; 1536   5586 ++cs;
HITCBC 1537   5586 u1_ += digit; 1537   5586 u1_ += digit;
HITCBC 1538   5586 if(BOOST_JSON_LIKELY( 1538   5586 if(BOOST_JSON_LIKELY(
1539   u1_ < 0xd800 || u1_ > 0xdfff)) 1539   u1_ < 0xd800 || u1_ > 0xdfff))
1540   { 1540   {
HITCBC 1541   1434 BOOST_ASSERT(temp.empty()); 1541   1434 BOOST_ASSERT(temp.empty());
1542   // utf-8 codepoint 1542   // utf-8 codepoint
HITCBC 1543   1434 temp.append_utf8(u1_); 1543   1434 temp.append_utf8(u1_);
HITCBC 1544   1434 break; 1544   1434 break;
1545   } 1545   }
HITCBC 1546   4152 if(BOOST_JSON_UNLIKELY(u1_ > 0xdbff)) 1546   4152 if(BOOST_JSON_UNLIKELY(u1_ > 0xdbff))
1547   { 1547   {
1548   // If it's an illegal leading surrogate and 1548   // If it's an illegal leading surrogate and
1549   // the parser does not allow it, return an error. 1549   // the parser does not allow it, return an error.
HITCBC 1550   1585 if(!allow_bad_utf16) 1550   1585 if(!allow_bad_utf16)
1551   { 1551   {
1552   BOOST_STATIC_CONSTEXPR source_location loc 1552   BOOST_STATIC_CONSTEXPR source_location loc
1553   = BOOST_CURRENT_LOCATION; 1553   = BOOST_CURRENT_LOCATION;
HITCBC 1554   209 return fail(cs.begin(), error::illegal_leading_surrogate, &loc); 1554   209 return fail(cs.begin(), error::illegal_leading_surrogate, &loc);
1555   } 1555   }
1556   // Otherwise, append the Unicode replacement character 1556   // Otherwise, append the Unicode replacement character
1557   else 1557   else
1558   { 1558   {
HITCBC 1559   1376 BOOST_ASSERT(temp.empty()); 1559   1376 BOOST_ASSERT(temp.empty());
HITCBC 1560   1376 temp.append_utf8(urc); 1560   1376 temp.append_utf8(urc);
HITCBC 1561   1376 break; 1561   1376 break;
1562   } 1562   }
1563   } 1563   }
HITCBC 1564   2567 do_sur1: 1564   2567 do_sur1:
HITCBC 1565   3792 if(BOOST_JSON_UNLIKELY(! cs)) 1565   3792 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1566   232 return maybe_suspend(cs.begin(), state::sur1); 1566   232 return maybe_suspend(cs.begin(), state::sur1);
HITCBC 1567   3560 if(BOOST_JSON_UNLIKELY(*cs != '\\')) 1567   3560 if(BOOST_JSON_UNLIKELY(*cs != '\\'))
1568   { 1568   {
1569   // If the next character is not a backslash and 1569   // If the next character is not a backslash and
1570   // the parser does not allow it, return a syntax error. 1570   // the parser does not allow it, return a syntax error.
HITCBC 1571   952 if(!allow_bad_utf16) 1571   952 if(!allow_bad_utf16)
1572   { 1572   {
1573   BOOST_STATIC_CONSTEXPR source_location loc 1573   BOOST_STATIC_CONSTEXPR source_location loc
1574   = BOOST_CURRENT_LOCATION; 1574   = BOOST_CURRENT_LOCATION;
HITCBC 1575   149 return fail(cs.begin(), error::syntax, &loc); 1575   149 return fail(cs.begin(), error::syntax, &loc);
1576   } 1576   }
1577   // Otherwise, append the Unicode replacement character since 1577   // Otherwise, append the Unicode replacement character since
1578   // the first code point is a valid leading surrogate 1578   // the first code point is a valid leading surrogate
1579   else 1579   else
1580   { 1580   {
HITCBC 1581   803 temp.append_utf8(urc); 1581   803 temp.append_utf8(urc);
HITCBC 1582   803 break; 1582   803 break;
1583   } 1583   }
1584   } 1584   }
HITCBC 1585   2608 ++cs; 1585   2608 ++cs;
HITCBC 1586   2796 do_sur2: 1586   2796 do_sur2:
HITCBC 1587   2796 if(BOOST_JSON_UNLIKELY(! cs)) 1587   2796 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1588   188 return maybe_suspend(cs.begin(), state::sur2); 1588   188 return maybe_suspend(cs.begin(), state::sur2);
HITCBC 1589   2608 if(BOOST_JSON_UNLIKELY(*cs != 'u')) 1589   2608 if(BOOST_JSON_UNLIKELY(*cs != 'u'))
1590   { 1590   {
HITCBC 1591   396 if (!allow_bad_utf16) 1591   396 if (!allow_bad_utf16)
1592   { 1592   {
1593   BOOST_STATIC_CONSTEXPR source_location loc 1593   BOOST_STATIC_CONSTEXPR source_location loc
1594   = BOOST_CURRENT_LOCATION; 1594   = BOOST_CURRENT_LOCATION;
HITCBC 1595   65 return fail(cs.begin(), error::syntax, &loc); 1595   65 return fail(cs.begin(), error::syntax, &loc);
1596   } 1596   }
1597   // Otherwise, append the Unicode replacement character since 1597   // Otherwise, append the Unicode replacement character since
1598   // the first code point is a valid leading surrogate 1598   // the first code point is a valid leading surrogate
1599   else 1599   else
1600   { 1600   {
HITCBC 1601   331 temp.append_utf8(urc); 1601   331 temp.append_utf8(urc);
HITCBC 1602   331 goto do_str3; 1602   331 goto do_str3;
1603   } 1603   }
1604   } 1604   }
HITCBC 1605   2212 ++cs; 1605   2212 ++cs;
HITCBC 1606   2376 do_sur3: 1606   2376 do_sur3:
HITCBC 1607   2376 if(BOOST_JSON_UNLIKELY(! cs)) 1607   2376 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1608   164 return maybe_suspend(cs.begin(), state::sur3); 1608   164 return maybe_suspend(cs.begin(), state::sur3);
HITCBC 1609   2212 digit = detail::hex_digit(*cs); 1609   2212 digit = detail::hex_digit(*cs);
HITCBC 1610   2212 if(BOOST_JSON_UNLIKELY(digit == -1)) 1610   2212 if(BOOST_JSON_UNLIKELY(digit == -1))
1611   { 1611   {
1612   BOOST_STATIC_CONSTEXPR source_location loc 1612   BOOST_STATIC_CONSTEXPR source_location loc
1613   = BOOST_CURRENT_LOCATION; 1613   = BOOST_CURRENT_LOCATION;
HITCBC 1614   35 return fail(cs.begin(), error::expected_hex_digit, &loc); 1614   35 return fail(cs.begin(), error::expected_hex_digit, &loc);
1615   } 1615   }
HITCBC 1616   2177 ++cs; 1616   2177 ++cs;
HITCBC 1617   2177 u2_ = digit << 12; 1617   2177 u2_ = digit << 12;
HITCBC 1618   2339 do_sur4: 1618   2339 do_sur4:
HITCBC 1619   2339 if(BOOST_JSON_UNLIKELY(! cs)) 1619   2339 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1620   162 return maybe_suspend(cs.begin(), state::sur4); 1620   162 return maybe_suspend(cs.begin(), state::sur4);
HITCBC 1621   2177 digit = detail::hex_digit(*cs); 1621   2177 digit = detail::hex_digit(*cs);
HITCBC 1622   2177 if(BOOST_JSON_UNLIKELY(digit == -1)) 1622   2177 if(BOOST_JSON_UNLIKELY(digit == -1))
1623   { 1623   {
1624   BOOST_STATIC_CONSTEXPR source_location loc 1624   BOOST_STATIC_CONSTEXPR source_location loc
1625   = BOOST_CURRENT_LOCATION; 1625   = BOOST_CURRENT_LOCATION;
HITCBC 1626   35 return fail(cs.begin(), error::expected_hex_digit, &loc); 1626   35 return fail(cs.begin(), error::expected_hex_digit, &loc);
1627   } 1627   }
HITCBC 1628   2142 ++cs; 1628   2142 ++cs;
HITCBC 1629   2142 u2_ += digit << 8; 1629   2142 u2_ += digit << 8;
HITCBC 1630   2302 do_sur5: 1630   2302 do_sur5:
HITCBC 1631   2302 if(BOOST_JSON_UNLIKELY(! cs)) 1631   2302 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1632   160 return maybe_suspend(cs.begin(), state::sur5); 1632   160 return maybe_suspend(cs.begin(), state::sur5);
HITCBC 1633   2142 digit = detail::hex_digit(*cs); 1633   2142 digit = detail::hex_digit(*cs);
HITCBC 1634   2142 if(BOOST_JSON_UNLIKELY(digit == -1)) 1634   2142 if(BOOST_JSON_UNLIKELY(digit == -1))
1635   { 1635   {
1636   BOOST_STATIC_CONSTEXPR source_location loc 1636   BOOST_STATIC_CONSTEXPR source_location loc
1637   = BOOST_CURRENT_LOCATION; 1637   = BOOST_CURRENT_LOCATION;
HITCBC 1638   20 return fail(cs.begin(), error::expected_hex_digit, &loc); 1638   20 return fail(cs.begin(), error::expected_hex_digit, &loc);
1639   } 1639   }
HITCBC 1640   2122 ++cs; 1640   2122 ++cs;
HITCBC 1641   2122 u2_ += digit << 4; 1641   2122 u2_ += digit << 4;
HITCBC 1642   2280 do_sur6: 1642   2280 do_sur6:
HITCBC 1643   2280 if(BOOST_JSON_UNLIKELY(! cs)) 1643   2280 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1644   158 return maybe_suspend(cs.begin(), state::sur6); 1644   158 return maybe_suspend(cs.begin(), state::sur6);
HITCBC 1645   2122 digit = detail::hex_digit(*cs); 1645   2122 digit = detail::hex_digit(*cs);
HITCBC 1646   2122 if(BOOST_JSON_UNLIKELY(digit == -1)) 1646   2122 if(BOOST_JSON_UNLIKELY(digit == -1))
1647   { 1647   {
1648   BOOST_STATIC_CONSTEXPR source_location loc 1648   BOOST_STATIC_CONSTEXPR source_location loc
1649   = BOOST_CURRENT_LOCATION; 1649   = BOOST_CURRENT_LOCATION;
HITCBC 1650   20 return fail(cs.begin(), error::expected_hex_digit, &loc); 1650   20 return fail(cs.begin(), error::expected_hex_digit, &loc);
1651   } 1651   }
HITCBC 1652   2102 ++cs; 1652   2102 ++cs;
HITCBC 1653   2102 u2_ += digit; 1653   2102 u2_ += digit;
1654   // Check if the second code point is a valid trailing surrogate. 1654   // Check if the second code point is a valid trailing surrogate.
1655   // Valid trailing surrogates are [DC00, DFFF] 1655   // Valid trailing surrogates are [DC00, DFFF]
HITCBC 1656   2102 if(BOOST_JSON_UNLIKELY( 1656   2102 if(BOOST_JSON_UNLIKELY(
1657   u2_ < 0xdc00 || u2_ > 0xdfff)) 1657   u2_ < 0xdc00 || u2_ > 0xdfff))
1658   { 1658   {
1659   // If not valid and the parser does not allow it, return an error. 1659   // If not valid and the parser does not allow it, return an error.
HITCBC 1660   580 if(!allow_bad_utf16) 1660   580 if(!allow_bad_utf16)
1661   { 1661   {
1662   BOOST_STATIC_CONSTEXPR source_location loc 1662   BOOST_STATIC_CONSTEXPR source_location loc
1663   = BOOST_CURRENT_LOCATION; 1663   = BOOST_CURRENT_LOCATION;
HITCBC 1664   60 return fail(cs.begin(), error::illegal_trailing_surrogate, &loc); 1664   60 return fail(cs.begin(), error::illegal_trailing_surrogate, &loc);
1665   } 1665   }
1666   // Append the replacement character for the 1666   // Append the replacement character for the
1667   // first leading surrogate. 1667   // first leading surrogate.
HITCBC 1668   520 temp.append_utf8(urc); 1668   520 temp.append_utf8(urc);
1669   // Check if the second code point is a 1669   // Check if the second code point is a
1670   // valid unicode scalar value (invalid leading 1670   // valid unicode scalar value (invalid leading
1671   // or trailing surrogate) 1671   // or trailing surrogate)
HITCBC 1672   520 if (u2_ < 0xd800 || u2_ > 0xdbff) 1672   520 if (u2_ < 0xd800 || u2_ > 0xdbff)
1673   { 1673   {
HITCBC 1674   220 temp.append_utf8(u2_); 1674   220 temp.append_utf8(u2_);
HITCBC 1675   220 break; 1675   220 break;
1676   } 1676   }
1677   // If it is a valid leading surrogate 1677   // If it is a valid leading surrogate
1678   else 1678   else
1679   { 1679   {
HITCBC 1680   300 u1_ = u2_; 1680   300 u1_ = u2_;
HITCBC 1681   300 goto do_sur1; 1681   300 goto do_sur1;
1682   } 1682   }
1683   } 1683   }
1684   // Calculate the Unicode code point from the surrogate pair and 1684   // Calculate the Unicode code point from the surrogate pair and
1685   // append the UTF-8 representation. 1685   // append the UTF-8 representation.
HITCBC 1686   1522 unsigned cp = 1686   1522 unsigned cp =
HITCBC 1687   1522 ((u1_ - 0xd800) << 10) + 1687   1522 ((u1_ - 0xd800) << 10) +
HITCBC 1688   1522 ((u2_ - 0xdc00)) + 1688   1522 ((u2_ - 0xdc00)) +
1689   0x10000; 1689   0x10000;
1690   // utf-16 surrogate pair 1690   // utf-16 surrogate pair
HITCBC 1691   1522 temp.append_utf8(cp); 1691   1522 temp.append_utf8(cp);
1692   } 1692   }
1693   1693  
1694   // flush 1694   // flush
HITCBC 1695   12653 if(BOOST_JSON_UNLIKELY( !cs ) || *cs != '\\') 1695   12653 if(BOOST_JSON_UNLIKELY( !cs ) || *cs != '\\')
HITCBC 1696   8870 break; 1696   8870 break;
1697   } 1697   }
1698   1698  
HITCBC 1699   8870 if(BOOST_JSON_LIKELY( temp.size() )) 1699   8870 if(BOOST_JSON_LIKELY( temp.size() ))
1700   { 1700   {
HITCBC 1701   434 BOOST_ASSERT(total <= max_size); 1701   434 BOOST_ASSERT(total <= max_size);
HITCBC 1702   8870 if(BOOST_JSON_UNLIKELY( temp.size() > max_size - total )) 1702   8870 if(BOOST_JSON_UNLIKELY( temp.size() > max_size - total ))
1703   { 1703   {
1704   BOOST_STATIC_CONSTEXPR source_location loc 1704   BOOST_STATIC_CONSTEXPR source_location loc
1705   = BOOST_CURRENT_LOCATION; 1705   = BOOST_CURRENT_LOCATION;
HITCBC 1706   1 return fail(cs.begin(), ev_too_large, &loc); 1706   1 return fail(cs.begin(), ev_too_large, &loc);
1707   } 1707   }
1708   1708  
HITCBC 1709   8869 total += temp.size(); 1709   8869 total += temp.size();
HITCBC 1710   8056 bool const r = is_key 1710   8056 bool const r = is_key
HITCBC 1711   8869 ? h_.on_key_part(temp.get(), total, ec_) 1711   8869 ? h_.on_key_part(temp.get(), total, ec_)
HITCBC 1712   8152 : h_.on_string_part(temp.get(), total, ec_); 1712   8152 : h_.on_string_part(temp.get(), total, ec_);
HITCBC 1713   8056 if(BOOST_JSON_UNLIKELY( !r )) 1713   8056 if(BOOST_JSON_UNLIKELY( !r ))
HITCBC 1714   813 return fail( cs.begin() ); 1714   813 return fail( cs.begin() );
1715   } 1715   }
1716   1716  
HITCBC 1717   7243 return cs.begin(); 1717   7243 return cs.begin();
1718   } 1718   }
1719   1719  
1720   //---------------------------------------------------------- 1720   //----------------------------------------------------------
1721   1721  
1722   template<class Handler> 1722   template<class Handler>
1723   template< 1723   template<
1724   bool StackEmpty_, 1724   bool StackEmpty_,
1725   bool AllowComments_/*, 1725   bool AllowComments_/*,
1726   bool AllowTrailing_, 1726   bool AllowTrailing_,
1727   bool AllowBadUTF8_*/> 1727   bool AllowBadUTF8_*/>
1728   const char* 1728   const char*
HITCBC 1729   109212 basic_parser<Handler>:: 1729   109212 basic_parser<Handler>::
1730   parse_object(const char* p, 1730   parse_object(const char* p,
1731   std::integral_constant<bool, StackEmpty_> stack_empty, 1731   std::integral_constant<bool, StackEmpty_> stack_empty,
1732   std::integral_constant<bool, AllowComments_> allow_comments, 1732   std::integral_constant<bool, AllowComments_> allow_comments,
1733   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 1733   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
1734   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 1734   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
1735   bool allow_bad_utf16) 1735   bool allow_bad_utf16)
1736   { 1736   {
HITCBC 1737   109212 detail::const_stream_wrapper cs(p, end_); 1737   109212 detail::const_stream_wrapper cs(p, end_);
1738   std::size_t size; 1738   std::size_t size;
HITCBC 1739   109212 if(! stack_empty && ! st_.empty()) 1739   109212 if(! stack_empty && ! st_.empty())
1740   { 1740   {
1741   // resume 1741   // resume
1742   state st; 1742   state st;
HITCBC 1743   35074 st_.pop(st); 1743   35074 st_.pop(st);
HITCBC 1744   35074 st_.pop(size); 1744   35074 st_.pop(size);
HITCBC 1745   35074 switch(st) 1745   35074 switch(st)
1746   { 1746   {
1747   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE 1747   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE
HITCBC 1748   1596 case state::obj1: goto do_obj1; 1748   1596 case state::obj1: goto do_obj1;
HITCBC 1749   235 case state::obj2: goto do_obj2; 1749   235 case state::obj2: goto do_obj2;
HITCBC 1750   12651 case state::obj3: goto do_obj3; 1750   12651 case state::obj3: goto do_obj3;
HITCBC 1751   1692 case state::obj4: goto do_obj4; 1751   1692 case state::obj4: goto do_obj4;
HITCBC 1752   251 case state::obj5: goto do_obj5; 1752   251 case state::obj5: goto do_obj5;
HITCBC 1753   1593 case state::obj6: goto do_obj6; 1753   1593 case state::obj6: goto do_obj6;
HITCBC 1754   15453 case state::obj7: goto do_obj7; 1754   15453 case state::obj7: goto do_obj7;
HITCBC 1755   427 case state::obj8: goto do_obj8; 1755   427 case state::obj8: goto do_obj8;
HITCBC 1756   661 case state::obj9: goto do_obj9; 1756   661 case state::obj9: goto do_obj9;
HITCBC 1757   181 case state::obj10: goto do_obj10; 1757   181 case state::obj10: goto do_obj10;
HITCBC 1758   334 case state::obj11: goto do_obj11; 1758   334 case state::obj11: goto do_obj11;
1759   } 1759   }
1760   } 1760   }
HITCBC 1761   74138 BOOST_ASSERT(*cs == '{'); 1761   74138 BOOST_ASSERT(*cs == '{');
HITCBC 1762   74138 size = 0; 1762   74138 size = 0;
HITCBC 1763   74138 if(BOOST_JSON_UNLIKELY(! depth_)) 1763   74138 if(BOOST_JSON_UNLIKELY(! depth_))
1764   { 1764   {
1765   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; 1765   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
HITCBC 1766   3 return fail(cs.begin(), error::too_deep, &loc); 1766   3 return fail(cs.begin(), error::too_deep, &loc);
1767   } 1767   }
HITCBC 1768   74135 --depth_; 1768   74135 --depth_;
HITCBC 1769   74135 if(BOOST_JSON_UNLIKELY( 1769   74135 if(BOOST_JSON_UNLIKELY(
1770   ! h_.on_object_begin(ec_))) 1770   ! h_.on_object_begin(ec_)))
HITCBC 1771   2040 return fail(cs.begin()); 1771   2040 return fail(cs.begin());
HITCBC 1772   70057 ++cs; 1772   70057 ++cs;
1773   // object: 1773   // object:
1774   // '{' *ws '}' 1774   // '{' *ws '}'
1775   // '{' *ws string *ws ':' *ws value *ws *[ ',' *ws string *ws ':' *ws value *ws ] '}' 1775   // '{' *ws string *ws ':' *ws value *ws *[ ',' *ws string *ws ':' *ws value *ws ] '}'
HITCBC 1776   73624 do_obj1: 1776   73624 do_obj1:
HITCBC 1777   73624 cs = detail::count_whitespace(cs.begin(), cs.end()); 1777   73624 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1778   73624 if(BOOST_JSON_UNLIKELY(! cs)) 1778   73624 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1779   1630 return maybe_suspend(cs.begin(), state::obj1, size); 1779   1630 return maybe_suspend(cs.begin(), state::obj1, size);
HITCBC 1780   71994 if(BOOST_JSON_LIKELY(*cs != '}')) 1780   71994 if(BOOST_JSON_LIKELY(*cs != '}'))
1781   { 1781   {
HITCBC 1782   69095 if(BOOST_JSON_UNLIKELY(*cs != '\x22')) 1782   69095 if(BOOST_JSON_UNLIKELY(*cs != '\x22'))
1783   { 1783   {
HITCBC 1784   2411 if(allow_comments && *cs == '/') 1784   2411 if(allow_comments && *cs == '/')
1785   { 1785   {
HITCBC 1786   2139 do_obj2: 1786   2139 do_obj2:
HITCBC 1787   2374 cs = parse_comment(cs.begin(), stack_empty, std::false_type()); 1787   2374 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
HITCBC 1788   2290 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1788   2290 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1789   319 return suspend_or_fail(state::obj2, size); 1789   319 return suspend_or_fail(state::obj2, size);
HITCBC 1790   1971 goto do_obj1; 1790   1971 goto do_obj1;
1791   } 1791   }
1792   BOOST_STATIC_CONSTEXPR source_location loc 1792   BOOST_STATIC_CONSTEXPR source_location loc
1793   = BOOST_CURRENT_LOCATION; 1793   = BOOST_CURRENT_LOCATION;
HITCBC 1794   272 return fail(cs.begin(), error::syntax, &loc); 1794   272 return fail(cs.begin(), error::syntax, &loc);
1795   } 1795   }
HITCBC 1796   66684 loop: 1796   66684 loop:
HITCBC 1797   80843 if(BOOST_JSON_UNLIKELY(++size > 1797   80843 if(BOOST_JSON_UNLIKELY(++size >
1798   Handler::max_object_size)) 1798   Handler::max_object_size))
1799   { 1799   {
1800   BOOST_STATIC_CONSTEXPR source_location loc 1800   BOOST_STATIC_CONSTEXPR source_location loc
1801   = BOOST_CURRENT_LOCATION; 1801   = BOOST_CURRENT_LOCATION;
HITCBC 1802   1 return fail(cs.begin(), error::object_too_large, &loc); 1802   1 return fail(cs.begin(), error::object_too_large, &loc);
1803   } 1803   }
HITCBC 1804   80842 do_obj3: 1804   80842 do_obj3:
HITCBC 1805   93493 cs = parse_string(cs.begin(), stack_empty, std::true_type(), allow_bad_utf8, allow_bad_utf16); 1805   93493 cs = parse_string(cs.begin(), stack_empty, std::true_type(), allow_bad_utf8, allow_bad_utf16);
HITCBC 1806   90537 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1806   90537 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1807   15596 return suspend_or_fail(state::obj3, size); 1807   15596 return suspend_or_fail(state::obj3, size);
HITCBC 1808   74941 do_obj4: 1808   74941 do_obj4:
HITCBC 1809   79104 cs = detail::count_whitespace(cs.begin(), cs.end()); 1809   79104 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1810   79104 if(BOOST_JSON_UNLIKELY(! cs)) 1810   79104 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1811   1707 return maybe_suspend(cs.begin(), state::obj4, size); 1811   1707 return maybe_suspend(cs.begin(), state::obj4, size);
HITCBC 1812   77397 if(BOOST_JSON_UNLIKELY(*cs != ':')) 1812   77397 if(BOOST_JSON_UNLIKELY(*cs != ':'))
1813   { 1813   {
HITCBC 1814   2925 if(allow_comments && *cs == '/') 1814   2925 if(allow_comments && *cs == '/')
1815   { 1815   {
HITCBC 1816   2779 do_obj5: 1816   2779 do_obj5:
HITCBC 1817   3030 cs = parse_comment(cs.begin(), stack_empty, std::false_type()); 1817   3030 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
HITCBC 1818   2876 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1818   2876 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1819   405 return suspend_or_fail(state::obj5, size); 1819   405 return suspend_or_fail(state::obj5, size);
HITCBC 1820   2471 goto do_obj4; 1820   2471 goto do_obj4;
1821   } 1821   }
1822   BOOST_STATIC_CONSTEXPR source_location loc 1822   BOOST_STATIC_CONSTEXPR source_location loc
1823   = BOOST_CURRENT_LOCATION; 1823   = BOOST_CURRENT_LOCATION;
HITCBC 1824   146 return fail(cs.begin(), error::syntax, &loc); 1824   146 return fail(cs.begin(), error::syntax, &loc);
1825   } 1825   }
HITCBC 1826   74472 ++cs; 1826   74472 ++cs;
HITCBC 1827   76065 do_obj6: 1827   76065 do_obj6:
HITCBC 1828   76065 cs = detail::count_whitespace(cs.begin(), cs.end()); 1828   76065 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1829   76065 if(BOOST_JSON_UNLIKELY(! cs)) 1829   76065 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1830   1624 return maybe_suspend(cs.begin(), state::obj6, size); 1830   1624 return maybe_suspend(cs.begin(), state::obj6, size);
HITCBC 1831   74441 do_obj7: 1831   74441 do_obj7:
HITCBC 1832   89894 cs = parse_value(cs.begin(), stack_empty, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 1832   89894 cs = parse_value(cs.begin(), stack_empty, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
HITCBC 1833   82545 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1833   82545 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1834   23598 return suspend_or_fail(state::obj7, size); 1834   23598 return suspend_or_fail(state::obj7, size);
HITCBC 1835   58947 do_obj8: 1835   58947 do_obj8:
HITCBC 1836   61210 cs = detail::count_whitespace(cs.begin(), cs.end()); 1836   61210 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1837   61210 if(BOOST_JSON_UNLIKELY(! cs)) 1837   61210 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1838   442 return maybe_suspend(cs.begin(), state::obj8, size); 1838   442 return maybe_suspend(cs.begin(), state::obj8, size);
HITCBC 1839   60768 if(BOOST_JSON_LIKELY(*cs == ',')) 1839   60768 if(BOOST_JSON_LIKELY(*cs == ','))
1840   { 1840   {
HITCBC 1841   17799 ++cs; 1841   17799 ++cs;
HITCBC 1842   19715 do_obj9: 1842   19715 do_obj9:
HITCBC 1843   19715 cs = detail::count_whitespace(cs.begin(), cs.end()); 1843   19715 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1844   19715 if(BOOST_JSON_UNLIKELY(! cs)) 1844   19715 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1845   691 return maybe_suspend(cs.begin(), state::obj9, size); 1845   691 return maybe_suspend(cs.begin(), state::obj9, size);
1846   1846  
1847   // loop for next element 1847   // loop for next element
HITCBC 1848   19024 if(BOOST_JSON_LIKELY(*cs == '\x22')) 1848   19024 if(BOOST_JSON_LIKELY(*cs == '\x22'))
HITCBC 1849   14159 goto loop; 1849   14159 goto loop;
HITCBC 1850   4865 if(! allow_trailing || *cs != '}') 1850   4865 if(! allow_trailing || *cs != '}')
1851   { 1851   {
HITCBC 1852   1644 if(allow_comments && *cs == '/') 1852   1644 if(allow_comments && *cs == '/')
1853   { 1853   {
HITCBC 1854   1433 do_obj10: 1854   1433 do_obj10:
HITCBC 1855   1614 cs = parse_comment(cs.begin(), stack_empty, std::false_type()); 1855   1614 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
HITCBC 1856   1525 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1856   1525 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1857   270 return suspend_or_fail(state::obj10, size); 1857   270 return suspend_or_fail(state::obj10, size);
HITCBC 1858   1255 goto do_obj9; 1858   1255 goto do_obj9;
1859   } 1859   }
1860   BOOST_STATIC_CONSTEXPR source_location loc 1860   BOOST_STATIC_CONSTEXPR source_location loc
1861   = BOOST_CURRENT_LOCATION; 1861   = BOOST_CURRENT_LOCATION;
HITCBC 1862   211 return fail(cs.begin(), error::syntax, &loc); 1862   211 return fail(cs.begin(), error::syntax, &loc);
1863   } 1863   }
1864   } 1864   }
HITCBC 1865   42969 else if(BOOST_JSON_UNLIKELY(*cs != '}')) 1865   42969 else if(BOOST_JSON_UNLIKELY(*cs != '}'))
1866   { 1866   {
HITCBC 1867   2325 if(allow_comments && *cs == '/') 1867   2325 if(allow_comments && *cs == '/')
1868   { 1868   {
HITCBC 1869   2172 do_obj11: 1869   2172 do_obj11:
HITCBC 1870   2506 cs = parse_comment(cs.begin(), stack_empty, std::false_type()); 1870   2506 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
HITCBC 1871   2338 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1871   2338 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1872   502 return suspend_or_fail(state::obj11, size); 1872   502 return suspend_or_fail(state::obj11, size);
HITCBC 1873   1836 goto do_obj8; 1873   1836 goto do_obj8;
1874   } 1874   }
1875   BOOST_STATIC_CONSTEXPR source_location loc 1875   BOOST_STATIC_CONSTEXPR source_location loc
1876   = BOOST_CURRENT_LOCATION; 1876   = BOOST_CURRENT_LOCATION;
HITCBC 1877   153 return fail(cs.begin(), error::syntax, &loc); 1877   153 return fail(cs.begin(), error::syntax, &loc);
1878   } 1878   }
1879   // got closing brace, fall through 1879   // got closing brace, fall through
1880   } 1880   }
HITCBC 1881   46764 if(BOOST_JSON_UNLIKELY( 1881   46764 if(BOOST_JSON_UNLIKELY(
1882   ! h_.on_object_end(size, ec_))) 1882   ! h_.on_object_end(size, ec_)))
HITCBC 1883   1502 return fail(cs.begin()); 1883   1502 return fail(cs.begin());
HITCBC 1884   43721 ++depth_; 1884   43721 ++depth_;
HITCBC 1885   43721 ++cs; 1885   43721 ++cs;
HITCBC 1886   43721 return cs.begin(); 1886   43721 return cs.begin();
1887   } 1887   }
1888   1888  
1889   //---------------------------------------------------------- 1889   //----------------------------------------------------------
1890   1890  
1891   template<class Handler> 1891   template<class Handler>
1892   template< 1892   template<
1893   bool StackEmpty_, 1893   bool StackEmpty_,
1894   bool AllowComments_/*, 1894   bool AllowComments_/*,
1895   bool AllowTrailing_, 1895   bool AllowTrailing_,
1896   bool AllowBadUTF8_*/> 1896   bool AllowBadUTF8_*/>
1897   const char* 1897   const char*
HITCBC 1898   26387 basic_parser<Handler>:: 1898   26387 basic_parser<Handler>::
1899   parse_array(const char* p, 1899   parse_array(const char* p,
1900   std::integral_constant<bool, StackEmpty_> stack_empty, 1900   std::integral_constant<bool, StackEmpty_> stack_empty,
1901   std::integral_constant<bool, AllowComments_> allow_comments, 1901   std::integral_constant<bool, AllowComments_> allow_comments,
1902   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 1902   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
1903   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 1903   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
1904   bool allow_bad_utf16) 1904   bool allow_bad_utf16)
1905   { 1905   {
HITCBC 1906   26387 detail::const_stream_wrapper cs(p, end_); 1906   26387 detail::const_stream_wrapper cs(p, end_);
1907   std::size_t size; 1907   std::size_t size;
HITCBC 1908   26387 if(! stack_empty && ! st_.empty()) 1908   26387 if(! stack_empty && ! st_.empty())
1909   { 1909   {
1910   // resume 1910   // resume
1911   state st; 1911   state st;
HITCBC 1912   5746 st_.pop(st); 1912   5746 st_.pop(st);
HITCBC 1913   5746 st_.pop(size); 1913   5746 st_.pop(size);
HITCBC 1914   5746 switch(st) 1914   5746 switch(st)
1915   { 1915   {
1916   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE 1916   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE
HITCBC 1917   1056 case state::arr1: goto do_arr1; 1917   1056 case state::arr1: goto do_arr1;
HITCBC 1918   384 case state::arr2: goto do_arr2; 1918   384 case state::arr2: goto do_arr2;
HITCBC 1919   2946 case state::arr3: goto do_arr3; 1919   2946 case state::arr3: goto do_arr3;
HITCBC 1920   392 case state::arr4: goto do_arr4; 1920   392 case state::arr4: goto do_arr4;
HITCBC 1921   674 case state::arr5: goto do_arr5; 1921   674 case state::arr5: goto do_arr5;
HITCBC 1922   294 case state::arr6: goto do_arr6; 1922   294 case state::arr6: goto do_arr6;
1923   } 1923   }
1924   } 1924   }
HITCBC 1925   20641 BOOST_ASSERT(*cs == '['); 1925   20641 BOOST_ASSERT(*cs == '[');
HITCBC 1926   20641 size = 0; 1926   20641 size = 0;
HITCBC 1927   20641 if(BOOST_JSON_UNLIKELY(! depth_)) 1927   20641 if(BOOST_JSON_UNLIKELY(! depth_))
1928   { 1928   {
1929   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; 1929   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
HITCBC 1930   34 return fail(cs.begin(), error::too_deep, &loc); 1930   34 return fail(cs.begin(), error::too_deep, &loc);
1931   } 1931   }
HITCBC 1932   20607 --depth_; 1932   20607 --depth_;
HITCBC 1933   20607 if(BOOST_JSON_UNLIKELY( 1933   20607 if(BOOST_JSON_UNLIKELY(
1934   ! h_.on_array_begin(ec_))) 1934   ! h_.on_array_begin(ec_)))
HITCBC 1935   812 return fail(cs.begin()); 1935   812 return fail(cs.begin());
HITCBC 1936   18989 ++cs; 1936   18989 ++cs;
1937   // array: 1937   // array:
1938   // '[' *ws ']' 1938   // '[' *ws ']'
1939   // '[' *ws value *ws *[ ',' *ws value *ws ] ']' 1939   // '[' *ws value *ws *[ ',' *ws value *ws ] ']'
HITCBC 1940   21578 do_arr1: 1940   21578 do_arr1:
HITCBC 1941   21578 cs = detail::count_whitespace(cs.begin(), cs.end()); 1941   21578 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1942   21578 if(BOOST_JSON_UNLIKELY(! cs)) 1942   21578 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1943   1077 return maybe_suspend(cs.begin(), state::arr1, size); 1943   1077 return maybe_suspend(cs.begin(), state::arr1, size);
HITCBC 1944   20501 if(BOOST_JSON_LIKELY(*cs != ']')) 1944   20501 if(BOOST_JSON_LIKELY(*cs != ']'))
1945   { 1945   {
HITCBC 1946   18753 loop: 1946   18753 loop:
HITCBC 1947   26232 if(allow_comments && *cs == '/') 1947   26232 if(allow_comments && *cs == '/')
1948   { 1948   {
HITCBC 1949   1789 do_arr2: 1949   1789 do_arr2:
HITCBC 1950   2173 cs = parse_comment(cs.begin(), stack_empty, std::false_type()); 1950   2173 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
HITCBC 1951   2045 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1951   2045 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1952   512 return suspend_or_fail(state::arr2, size); 1952   512 return suspend_or_fail(state::arr2, size);
HITCBC 1953   1533 goto do_arr1; 1953   1533 goto do_arr1;
1954   } 1954   }
HITCBC 1955   24443 if(BOOST_JSON_UNLIKELY(++size > 1955   24443 if(BOOST_JSON_UNLIKELY(++size >
1956   Handler::max_array_size)) 1956   Handler::max_array_size))
1957   { 1957   {
1958   BOOST_STATIC_CONSTEXPR source_location loc 1958   BOOST_STATIC_CONSTEXPR source_location loc
1959   = BOOST_CURRENT_LOCATION; 1959   = BOOST_CURRENT_LOCATION;
HITCBC 1960   1 return fail(cs.begin(), error::array_too_large, &loc); 1960   1 return fail(cs.begin(), error::array_too_large, &loc);
1961   } 1961   }
HITCBC 1962   24442 do_arr3: 1962   24442 do_arr3:
1963   // array is not empty, value required 1963   // array is not empty, value required
HITCBC 1964   27388 cs = parse_value(cs.begin(), stack_empty, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16); 1964   27388 cs = parse_value(cs.begin(), stack_empty, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
HITCBC 1965   24757 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1965   24757 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1966   9060 return suspend_or_fail(state::arr3, size); 1966   9060 return suspend_or_fail(state::arr3, size);
HITCBC 1967   15697 do_arr4: 1967   15697 do_arr4:
HITCBC 1968   17319 cs = detail::count_whitespace(cs.begin(), cs.end()); 1968   17319 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1969   17319 if(BOOST_JSON_UNLIKELY(! cs)) 1969   17319 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1970   501 return maybe_suspend(cs.begin(), state::arr4, size); 1970   501 return maybe_suspend(cs.begin(), state::arr4, size);
HITCBC 1971   16818 if(BOOST_JSON_LIKELY(*cs == ',')) 1971   16818 if(BOOST_JSON_LIKELY(*cs == ','))
1972   { 1972   {
HITCBC 1973   9192 ++cs; 1973   9192 ++cs;
HITCBC 1974   9866 do_arr5: 1974   9866 do_arr5:
HITCBC 1975   9866 cs = detail::count_whitespace(cs.begin(), cs.end()); 1975   9866 cs = detail::count_whitespace(cs.begin(), cs.end());
HITCBC 1976   9866 if(BOOST_JSON_UNLIKELY(! cs)) 1976   9866 if(BOOST_JSON_UNLIKELY(! cs))
HITCBC 1977   704 return maybe_suspend(cs.begin(), state::arr5, size); 1977   704 return maybe_suspend(cs.begin(), state::arr5, size);
1978   // loop for next element 1978   // loop for next element
HITCBC 1979   9162 if(! allow_trailing || *cs != ']') 1979   9162 if(! allow_trailing || *cs != ']')
HITCBC 1980   7479 goto loop; 1980   7479 goto loop;
1981   } 1981   }
HITCBC 1982   7626 else if(BOOST_JSON_UNLIKELY(*cs != ']')) 1982   7626 else if(BOOST_JSON_UNLIKELY(*cs != ']'))
1983   { 1983   {
HITCBC 1984   1969 if(allow_comments && *cs == '/') 1984   1969 if(allow_comments && *cs == '/')
1985   { 1985   {
HITCBC 1986   1541 do_arr6: 1986   1541 do_arr6:
HITCBC 1987   1835 cs = parse_comment(cs.begin(), stack_empty, std::false_type()); 1987   1835 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
HITCBC 1988   1688 if(BOOST_JSON_UNLIKELY(incomplete(cs))) 1988   1688 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
HITCBC 1989   458 return suspend_or_fail(state::arr6, size); 1989   458 return suspend_or_fail(state::arr6, size);
HITCBC 1990   1230 goto do_arr4; 1990   1230 goto do_arr4;
1991   } 1991   }
1992   BOOST_STATIC_CONSTEXPR source_location loc 1992   BOOST_STATIC_CONSTEXPR source_location loc
1993   = BOOST_CURRENT_LOCATION; 1993   = BOOST_CURRENT_LOCATION;
HITCBC 1994   428 return fail(cs.begin(), error::syntax, &loc); 1994   428 return fail(cs.begin(), error::syntax, &loc);
1995   } 1995   }
1996   // got closing bracket; fall through 1996   // got closing bracket; fall through
1997   } 1997   }
HITCBC 1998   9088 if(BOOST_JSON_UNLIKELY( 1998   9088 if(BOOST_JSON_UNLIKELY(
1999   ! h_.on_array_end(size, ec_))) 1999   ! h_.on_array_end(size, ec_)))
HITCBC 2000   549 return fail(cs.begin()); 2000   549 return fail(cs.begin());
HITCBC 2001   7960 ++depth_; 2001   7960 ++depth_;
HITCBC 2002   7960 ++cs; 2002   7960 ++cs;
HITCBC 2003   7960 return cs.begin(); 2003   7960 return cs.begin();
2004   } 2004   }
2005   2005  
2006   //---------------------------------------------------------- 2006   //----------------------------------------------------------
2007   2007  
2008   template<class Handler> 2008   template<class Handler>
2009   template<bool StackEmpty_, char First_, number_precision Numbers_> 2009   template<bool StackEmpty_, char First_, number_precision Numbers_>
2010   const char* 2010   const char*
HITCBC 2011   10516036 basic_parser<Handler>:: 2011   10516036 basic_parser<Handler>::
2012   parse_number(const char* p, 2012   parse_number(const char* p,
2013   std::integral_constant<bool, StackEmpty_> stack_empty, 2013   std::integral_constant<bool, StackEmpty_> stack_empty,
2014   std::integral_constant<char, First_> first, 2014   std::integral_constant<char, First_> first,
2015   std::integral_constant<number_precision, Numbers_> mode) 2015   std::integral_constant<number_precision, Numbers_> mode)
2016   { 2016   {
HITCBC 2017   10516036 constexpr bool precise_parsing = mode == number_precision::precise; 2017   10516036 constexpr bool precise_parsing = mode == number_precision::precise;
HITCBC 2018   10516036 constexpr bool no_parsing = mode == number_precision::none; 2018   10516036 constexpr bool no_parsing = mode == number_precision::none;
2019   2019  
2020   // only one of these will be true if we are not resuming 2020   // only one of these will be true if we are not resuming
2021   // if negative then !zero_first && !nonzero_first 2021   // if negative then !zero_first && !nonzero_first
2022   // if zero_first then !nonzero_first && !negative 2022   // if zero_first then !nonzero_first && !negative
2023   // if nonzero_first then !zero_first && !negative 2023   // if nonzero_first then !zero_first && !negative
HITCBC 2024   10516036 bool const negative = first == '-'; 2024   10516036 bool const negative = first == '-';
HITCBC 2025   10516036 bool const zero_first = first == '0'; 2025   10516036 bool const zero_first = first == '0';
HITCBC 2026   10516036 bool const nonzero_first = first == '+'; 2026   10516036 bool const nonzero_first = first == '+';
HITCBC 2027   10516036 detail::const_stream_wrapper cs(p, end_); 2027   10516036 detail::const_stream_wrapper cs(p, end_);
2028   number num; 2028   number num;
HITCBC 2029   10516036 const char* begin = cs.begin(); 2029   10516036 const char* begin = cs.begin();
HITCBC 2030   10516036 if(stack_empty || st_.empty()) 2030   10516036 if(stack_empty || st_.empty())
2031   { 2031   {
HITCBC 2032   2090010 num.bias = 0; 2032   2090010 num.bias = 0;
HITCBC 2033   2090010 num.exp = 0; 2033   2090010 num.exp = 0;
HITCBC 2034   2090010 num.frac = false; 2034   2090010 num.frac = false;
HITCBC 2035   2090010 num_buf_.clear(); 2035   2090010 num_buf_.clear();
2036   2036  
2037   //---------------------------------- 2037   //----------------------------------
2038   // 2038   //
2039   // '-' 2039   // '-'
2040   // leading minus sign 2040   // leading minus sign
2041   // 2041   //
HITCBC 2042   2090010 BOOST_ASSERT(cs); 2042   2090010 BOOST_ASSERT(cs);
2043   if(negative) 2043   if(negative)
HITCBC 2044   25185 ++cs; 2044   25185 ++cs;
2045   2045  
HITCBC 2046   2090010 num.neg = negative; 2046   2090010 num.neg = negative;
HITCBC 2047   2090010 num.frac = false; 2047   2090010 num.frac = false;
HITCBC 2048   2090010 num.exp = 0; 2048   2090010 num.exp = 0;
HITCBC 2049   2090010 num.bias = 0; 2049   2090010 num.bias = 0;
2050   2050  
2051   // fast path 2051   // fast path
HITCBC 2052   2090010 if( cs.remain() >= 16 + 1 + 16 ) // digits . digits 2052   2090010 if( cs.remain() >= 16 + 1 + 16 ) // digits . digits
2053   { 2053   {
2054   int n1; 2054   int n1;
2055   2055  
HITCBC 2056   9989 if( nonzero_first || 2056   9989 if( nonzero_first ||
HITCBC 2057   9989 (negative && *cs != '0') ) 2057   9989 (negative && *cs != '0') )
2058   { 2058   {
HITCBC 2059   2007319 n1 = detail::count_digits( cs.begin() ); 2059   2007319 n1 = detail::count_digits( cs.begin() );
HITCBC 2060   2007319 BOOST_ASSERT(n1 >= 0 && n1 <= 16); 2060   2007319 BOOST_ASSERT(n1 >= 0 && n1 <= 16);
2061   2061  
HITCBC 2062   1837 if( negative && n1 == 0 && opt_.allow_infinity_and_nan ) 2062   1837 if( negative && n1 == 0 && opt_.allow_infinity_and_nan )
2063   { 2063   {
HITCBC 2064   9 return parse_literal( 2064   9 return parse_literal(
2065   p - 1, 2065   p - 1,
HITCBC 2066   8 detail::literals_c<detail::literals::neg_infinity>()); 2066   8 detail::literals_c<detail::literals::neg_infinity>());
2067   } 2067   }
2068   2068  
HITCBC 2069   1828 if( ! nonzero_first && n1 == 0 ) 2069   1828 if( ! nonzero_first && n1 == 0 )
2070   { 2070   {
2071   // digit required 2071   // digit required
2072   BOOST_STATIC_CONSTEXPR source_location loc 2072   BOOST_STATIC_CONSTEXPR source_location loc
2073   = BOOST_CURRENT_LOCATION; 2073   = BOOST_CURRENT_LOCATION;
HITCBC 2074   2 return fail(cs.begin(), error::syntax, &loc); 2074   2 return fail(cs.begin(), error::syntax, &loc);
2075   } 2075   }
2076   2076  
2077   BOOST_IF_CONSTEXPR( !no_parsing ) 2077   BOOST_IF_CONSTEXPR( !no_parsing )
HITCBC 2078   2006460 num.mant = detail::parse_unsigned( 0, cs.begin(), n1 ); 2078   2006460 num.mant = detail::parse_unsigned( 0, cs.begin(), n1 );
2079   else 2079   else
HITCBC 2080   848 num.mant = 0; 2080   848 num.mant = 0;
2081   2081  
HITCBC 2082   2007308 cs += n1; 2082   2007308 cs += n1;
2083   2083  
2084   // integer or floating-point with 2084   // integer or floating-point with
2085   // >= 16 leading digits 2085   // >= 16 leading digits
HITCBC 2086   2007308 if( n1 == 16 ) 2086   2007308 if( n1 == 16 )
2087   { 2087   {
HITCBC 2088   2001425 goto do_num2; 2088   2001425 goto do_num2;
2089   } 2089   }
2090   } 2090   }
2091   else 2091   else
2092   { 2092   {
2093   // 0. floating-point or 0e integer 2093   // 0. floating-point or 0e integer
HITCBC 2094   21187 num.mant = 0; 2094   21187 num.mant = 0;
HITCBC 2095   21187 n1 = 0; 2095   21187 n1 = 0;
HITCBC 2096   21187 ++cs; 2096   21187 ++cs;
2097   } 2097   }
2098   2098  
2099   { 2099   {
HITCBC 2100   27070 const char c = *cs; 2100   27070 const char c = *cs;
HITCBC 2101   27070 if(c != '.') 2101   27070 if(c != '.')
2102   { 2102   {
HITCBC 2103   9871 if((c | 32) == 'e') 2103   9871 if((c | 32) == 'e')
2104   { 2104   {
HITCBC 2105   6576 ++cs; 2105   6576 ++cs;
HITCBC 2106   6576 goto do_exp1; 2106   6576 goto do_exp1;
2107   } 2107   }
2108   BOOST_IF_CONSTEXPR( negative && !no_parsing ) 2108   BOOST_IF_CONSTEXPR( negative && !no_parsing )
HITCBC 2109   20 num.mant = ~num.mant + 1; 2109   20 num.mant = ~num.mant + 1;
HITCBC 2110   3295 goto finish_signed; 2110   3295 goto finish_signed;
2111   } 2111   }
2112   } 2112   }
2113   2113  
2114   // floating-point number 2114   // floating-point number
2115   2115  
HITCBC 2116   17199 ++cs; 2116   17199 ++cs;
2117   2117  
HITCBC 2118   17199 int n2 = detail::count_digits( cs.begin() ); 2118   17199 int n2 = detail::count_digits( cs.begin() );
HITCBC 2119   17199 BOOST_ASSERT(n2 >= 0 && n2 <= 16); 2119   17199 BOOST_ASSERT(n2 >= 0 && n2 <= 16);
2120   2120  
HITCBC 2121   17199 if( n2 == 0 ) 2121   17199 if( n2 == 0 )
2122   { 2122   {
2123   // digit required 2123   // digit required
2124   BOOST_STATIC_CONSTEXPR source_location loc 2124   BOOST_STATIC_CONSTEXPR source_location loc
2125   = BOOST_CURRENT_LOCATION; 2125   = BOOST_CURRENT_LOCATION;
HITCBC 2126   3 return fail(cs.begin(), error::syntax, &loc); 2126   3 return fail(cs.begin(), error::syntax, &loc);
2127   } 2127   }
2128   2128  
2129   // floating-point mantissa overflow 2129   // floating-point mantissa overflow
HITCBC 2130   17196 if( n1 + n2 >= 19 ) 2130   17196 if( n1 + n2 >= 19 )
2131   { 2131   {
HITCBC 2132   122 goto do_num7; 2132   122 goto do_num7;
2133   } 2133   }
2134   2134  
2135   BOOST_IF_CONSTEXPR( !no_parsing ) 2135   BOOST_IF_CONSTEXPR( !no_parsing )
HITCBC 2136   12855 num.mant = detail::parse_unsigned( num.mant, cs.begin(), n2 ); 2136   12855 num.mant = detail::parse_unsigned( num.mant, cs.begin(), n2 );
2137   2137  
HITCBC 2138   17074 BOOST_ASSERT(num.bias == 0); 2138   17074 BOOST_ASSERT(num.bias == 0);
2139   2139  
HITCBC 2140   17074 num.bias -= n2; 2140   17074 num.bias -= n2;
2141   2141  
HITCBC 2142   17074 cs += n2; 2142   17074 cs += n2;
2143   2143  
HITCBC 2144   17074 char ch = *cs; 2144   17074 char ch = *cs;
2145   2145  
HITCBC 2146   17074 if( (ch | 32) == 'e' ) 2146   17074 if( (ch | 32) == 'e' )
2147   { 2147   {
HITCBC 2148   110 ++cs; 2148   110 ++cs;
HITCBC 2149   110 goto do_exp1; 2149   110 goto do_exp1;
2150   } 2150   }
HITCBC 2151   16964 else if( ch >= '0' && ch <= '9' ) 2151   16964 else if( ch >= '0' && ch <= '9' )
2152   { 2152   {
HITCBC 2153   10017 goto do_num8; 2153   10017 goto do_num8;
2154   } 2154   }
2155   2155  
HITCBC 2156   6947 goto finish_dub; 2156   6947 goto finish_dub;
2157   } 2157   }
2158   } 2158   }
2159   else 2159   else
2160   { 2160   {
HITCBC 2161   8426026 num = num_; 2161   8426026 num = num_;
2162   state st; 2162   state st;
HITCBC 2163   8426026 st_.pop(st); 2163   8426026 st_.pop(st);
HITCBC 2164   8426026 switch(st) 2164   8426026 switch(st)
2165   { 2165   {
2166   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE 2166   default: BOOST_JSON_UNREACHABLE(); // LCOV_EXCL_LINE
HITCBC 2167   603 case state::num1: goto do_num1; 2167   603 case state::num1: goto do_num1;
HITCBC 2168   6467 case state::num2: goto do_num2; 2168   6467 case state::num2: goto do_num2;
HITCBC 2169   4195112 case state::num3: goto do_num3; 2169   4195112 case state::num3: goto do_num3;
HITCBC 2170   52 case state::num4: goto do_num4; 2170   52 case state::num4: goto do_num4;
HITCBC 2171   4537 case state::num5: goto do_num5; 2171   4537 case state::num5: goto do_num5;
HITCBC 2172   668 case state::num6: goto do_num6; 2172   668 case state::num6: goto do_num6;
HITCBC 2173   618 case state::num7: goto do_num7; 2173   618 case state::num7: goto do_num7;
HITCBC 2174   4205248 case state::num8: goto do_num8; 2174   4205248 case state::num8: goto do_num8;
HITCBC 2175   477 case state::exp1: goto do_exp1; 2175   477 case state::exp1: goto do_exp1;
HITCBC 2176   139 case state::exp2: goto do_exp2; 2176   139 case state::exp2: goto do_exp2;
HITCBC 2177   12105 case state::exp3: goto do_exp3; 2177   12105 case state::exp3: goto do_exp3;
2178   } 2178   }
2179   } 2179   }
2180   2180  
2181   //---------------------------------- 2181   //----------------------------------
2182   // 2182   //
2183   // DIGIT 2183   // DIGIT
2184   // first digit 2184   // first digit
2185   // 2185   //
HITCBC 2186   62107 do_num1: 2186   62107 do_num1:
HITCBC 2187   15799 if(zero_first || nonzero_first || 2187   15799 if(zero_first || nonzero_first ||
HITCBC 2188   15799 BOOST_JSON_LIKELY(cs)) 2188   15799 BOOST_JSON_LIKELY(cs))
2189   { 2189   {
HITCBC 2190   61384 char const c = *cs; 2190   61384 char const c = *cs;
2191   if(zero_first) 2191   if(zero_first)
2192   { 2192   {
HITCBC 2193   9726 ++cs; 2193   9726 ++cs;
HITCBC 2194   9726 num.mant = 0; 2194   9726 num.mant = 0;
HITCBC 2195   9726 goto do_num6; 2195   9726 goto do_num6;
2196   } 2196   }
HITCBC 2197   15076 else if(nonzero_first || BOOST_JSON_LIKELY( 2197   15076 else if(nonzero_first || BOOST_JSON_LIKELY(
2198   c >= '1' && c <= '9')) 2198   c >= '1' && c <= '9'))
2199   { 2199   {
HITCBC 2200   42829 ++cs; 2200   42829 ++cs;
HITCBC 2201   42829 num.mant = c - '0'; 2201   42829 num.mant = c - '0';
2202   } 2202   }
HITCBC 2203   8829 else if(BOOST_JSON_UNLIKELY( 2203   8829 else if(BOOST_JSON_UNLIKELY(
2204   c == '0')) 2204   c == '0'))
2205   { 2205   {
HITCBC 2206   7634 ++cs; 2206   7634 ++cs;
HITCBC 2207   7634 num.mant = 0; 2207   7634 num.mant = 0;
HITCBC 2208   7634 goto do_num6; 2208   7634 goto do_num6;
2209   } 2209   }
HITCBC 2210   1195 else if( (negative || num.neg) && opt_.allow_infinity_and_nan ) 2210   1195 else if( (negative || num.neg) && opt_.allow_infinity_and_nan )
2211   { 2211   {
HITCBC 2212   1007 st_.push(state::lit1); 2212   1007 st_.push(state::lit1);
HITCBC 2213   1007 cur_lit_ = literal_index(detail::literals::neg_infinity); 2213   1007 cur_lit_ = literal_index(detail::literals::neg_infinity);
HITCBC 2214   1007 lit_offset_ = 1; 2214   1007 lit_offset_ = 1;
HITCBC 2215   1007 return parse_literal( 2215   1007 return parse_literal(
HITCBC 2216   961 cs.begin(), detail::literals_c<detail::literals::resume>() ); 2216   961 cs.begin(), detail::literals_c<detail::literals::resume>() );
2217   } 2217   }
2218   else 2218   else
2219   { 2219   {
2220   BOOST_STATIC_CONSTEXPR source_location loc 2220   BOOST_STATIC_CONSTEXPR source_location loc
2221   = BOOST_CURRENT_LOCATION; 2221   = BOOST_CURRENT_LOCATION;
HITCBC 2222   188 return fail(cs.begin(), error::syntax, &loc); 2222   188 return fail(cs.begin(), error::syntax, &loc);
2223   } 2223   }
2224   } 2224   }
2225   else 2225   else
2226   { 2226   {
HITCBC 2227   723 if(BOOST_JSON_UNLIKELY( 2227   723 if(BOOST_JSON_UNLIKELY(
2228   ! h_.on_number_part( 2228   ! h_.on_number_part(
2229   {begin, cs.used(begin)}, ec_))) 2229   {begin, cs.used(begin)}, ec_)))
HITCBC 2230   60 return fail(cs.begin()); 2230   60 return fail(cs.begin());
2231   2231  
2232   BOOST_IF_CONSTEXPR( precise_parsing ) 2232   BOOST_IF_CONSTEXPR( precise_parsing )
MISUBC 2233   ✗ num_buf_.append( begin, cs.used(begin) ); 2233   ✗ num_buf_.append( begin, cs.used(begin) );
HITCBC 2234   603 return maybe_suspend( 2234   603 return maybe_suspend(
HITCBC 2235   603 cs.begin(), state::num1, num); 2235   603 cs.begin(), state::num1, num);
2236   } 2236   }
2237   2237  
2238   //---------------------------------- 2238   //----------------------------------
2239   // 2239   //
2240   // 1*DIGIT 2240   // 1*DIGIT
2241   // significant digits left of decimal 2241   // significant digits left of decimal
2242   // 2242   //
HITCBC 2243   2050721 do_num2: 2243   2050721 do_num2:
HITCBC 2244   2044463 if(negative || (!stack_empty && num.neg)) 2244   2044463 if(negative || (!stack_empty && num.neg))
2245   { 2245   {
HITCBC 2246   22400 for(;;) 2246   22400 for(;;)
2247   { 2247   {
HITCBC 2248   30225 if(BOOST_JSON_UNLIKELY(! cs)) 2248   30225 if(BOOST_JSON_UNLIKELY(! cs))
2249   { 2249   {
HITCBC 2250   1921 if(BOOST_JSON_UNLIKELY(more_)) 2250   1921 if(BOOST_JSON_UNLIKELY(more_))
2251   { 2251   {
HITCBC 2252   1469 if(BOOST_JSON_UNLIKELY( 2252   1469 if(BOOST_JSON_UNLIKELY(
2253   ! h_.on_number_part( 2253   ! h_.on_number_part(
2254   {begin, cs.used(begin)}, ec_))) 2254   {begin, cs.used(begin)}, ec_)))
HITCBC 2255   69 return fail(cs.begin()); 2255   69 return fail(cs.begin());
2256   2256  
2257   BOOST_IF_CONSTEXPR( precise_parsing ) 2257   BOOST_IF_CONSTEXPR( precise_parsing )
MISUBC 2258   ✗ num_buf_.append( begin, cs.used(begin) ); 2258   ✗ num_buf_.append( begin, cs.used(begin) );
HITCBC 2259   1331 return suspend(cs.begin(), state::num2, num); 2259   1331 return suspend(cs.begin(), state::num2, num);
2260   } 2260   }
HITCBC 2261   452 goto finish_int; 2261   452 goto finish_int;
2262   } 2262   }
HITCBC 2263   28304 char const c = *cs; 2263   28304 char const c = *cs;
HITCBC 2264   28304 if(BOOST_JSON_LIKELY( 2264   28304 if(BOOST_JSON_LIKELY(
2265   c >= '0' && c <= '9')) 2265   c >= '0' && c <= '9'))
2266   { 2266   {
HITCBC 2267   23223 ++cs; 2267   23223 ++cs;
2268   // 9223372036854775808 INT64_MIN 2268   // 9223372036854775808 INT64_MIN
HITCBC 2269   23223 if( num.mant > 922337203685477580 || ( 2269   23223 if( num.mant > 922337203685477580 || (
HITCBC 2270   22508 num.mant == 922337203685477580 && c > '8')) 2270   22508 num.mant == 922337203685477580 && c > '8'))
2271   break; 2271   break;
2272   BOOST_IF_CONSTEXPR( !no_parsing ) 2272   BOOST_IF_CONSTEXPR( !no_parsing )
HITCBC 2273   22141 num.mant = 10 * num.mant + ( c - '0' ); 2273   22141 num.mant = 10 * num.mant + ( c - '0' );
HITCBC 2274   22400 continue; 2274   22400 continue;
2275   } 2275   }
HITCBC 2276   5081 goto do_num6; // [.eE] 2276   5081 goto do_num6; // [.eE]
2277   } 2277   }
2278   } 2278   }
2279   else 2279   else
2280   { 2280   {
HITCBC 2281   6889563 for(;;) 2281   6889563 for(;;)
2282   { 2282   {
HITCBC 2283   8932459 if(BOOST_JSON_UNLIKELY(! cs)) 2283   8932459 if(BOOST_JSON_UNLIKELY(! cs))
2284   { 2284   {
HITCBC 2285   6595 if(BOOST_JSON_UNLIKELY(more_)) 2285   6595 if(BOOST_JSON_UNLIKELY(more_))
2286   { 2286   {
HITCBC 2287   5982 if(BOOST_JSON_UNLIKELY( 2287   5982 if(BOOST_JSON_UNLIKELY(
2288   ! h_.on_number_part( 2288   ! h_.on_number_part(
2289   {begin, cs.used(begin)}, ec_))) 2289   {begin, cs.used(begin)}, ec_)))
HITCBC 2290   426 return fail(cs.begin()); 2290   426 return fail(cs.begin());
2291   2291  
2292   BOOST_IF_CONSTEXPR( precise_parsing ) 2292   BOOST_IF_CONSTEXPR( precise_parsing )
MISUBC 2293   ✗ num_buf_.append( begin, cs.used(begin) ); 2293   ✗ num_buf_.append( begin, cs.used(begin) );
HITCBC 2294   5136 return suspend(cs.begin(), state::num2, num); 2294   5136 return suspend(cs.begin(), state::num2, num);
2295   } 2295   }
HITCBC 2296   613 goto finish_int; 2296   613 goto finish_int;
2297   } 2297   }
HITCBC 2298   8925864 char const c = *cs; 2298   8925864 char const c = *cs;
HITCBC 2299   8925864 if(BOOST_JSON_LIKELY( 2299   8925864 if(BOOST_JSON_LIKELY(
2300   c >= '0' && c <= '9')) 2300   c >= '0' && c <= '9'))
2301   { 2301   {
HITCBC 2302   6893607 ++cs; 2302   6893607 ++cs;
2303   // 18446744073709551615 UINT64_MAX 2303   // 18446744073709551615 UINT64_MAX
HITCBC 2304   6893607 if( num.mant > 1844674407370955161 || ( 2304   6893607 if( num.mant > 1844674407370955161 || (
HITCBC 2305   6889985 num.mant == 1844674407370955161 && c > '5')) 2305   6889985 num.mant == 1844674407370955161 && c > '5'))
2306   break; 2306   break;
2307   BOOST_IF_CONSTEXPR( !no_parsing ) 2307   BOOST_IF_CONSTEXPR( !no_parsing )
HITCBC 2308   6883965 num.mant = 10 * num.mant + ( c - '0' ); 2308   6883965 num.mant = 10 * num.mant + ( c - '0' );
2309   } 2309   }
2310   else 2310   else
2311   { 2311   {
HITCBC 2312   2032257 goto do_num6; // [.eE] 2312   2032257 goto do_num6; // [.eE]
2313   } 2313   }
2314   } 2314   }
2315   } 2315   }
HITCBC 2316   4867 ++num.bias; 2316   4867 ++num.bias;
2317   2317  
2318   //---------------------------------- 2318   //----------------------------------
2319   // 2319   //
2320   // 1*DIGIT 2320   // 1*DIGIT
2321   // non-significant digits left of decimal 2321   // non-significant digits left of decimal
2322   // 2322   //
HITCBC 2323   4199979 do_num3: 2323   4199979 do_num3:
HITCBC 2324   4294978560 for(;;) 2324   4294978560 for(;;)
2325   { 2325   {
HITCBC 2326   4299178539 if(BOOST_JSON_UNLIKELY(! cs)) 2326   4299178539 if(BOOST_JSON_UNLIKELY(! cs))
2327   { 2327   {
HITCBC 2328   4195839 if(BOOST_JSON_UNLIKELY(more_)) 2328   4195839 if(BOOST_JSON_UNLIKELY(more_))
2329   { 2329   {
HITCBC 2330   4195206 if(BOOST_JSON_UNLIKELY( 2330   4195206 if(BOOST_JSON_UNLIKELY(
2331   ! h_.on_number_part( 2331   ! h_.on_number_part(
2332   {begin, cs.used(begin)}, ec_))) 2332   {begin, cs.used(begin)}, ec_)))
HITCBC 2333   47 return fail(cs.begin()); 2333   47 return fail(cs.begin());
2334   2334  
2335   BOOST_IF_CONSTEXPR( precise_parsing ) 2335   BOOST_IF_CONSTEXPR( precise_parsing )
MISUBC 2336   ✗ num_buf_.append( begin, cs.used(begin) ); 2336   ✗ num_buf_.append( begin, cs.used(begin) );
HITCBC 2337   4195112 return suspend(cs.begin(), state::num3, num); 2337   4195112 return suspend(cs.begin(), state::num3, num);
2338   } 2338   }
HITCBC 2339   633 goto finish_dub; 2339   633 goto finish_dub;
2340   } 2340   }
HITCBC 2341   4294982700 char const c = *cs; 2341   4294982700 char const c = *cs;
HITCBC 2342   4294982700 if(BOOST_JSON_UNLIKELY( 2342   4294982700 if(BOOST_JSON_UNLIKELY(
2343   c >= '0' && c <= '9')) 2343   c >= '0' && c <= '9'))
2344   { 2344   {
HITCBC 2345   4294978561 if(BOOST_JSON_UNLIKELY( num.bias + 1 == INT_MAX )) 2345   4294978561 if(BOOST_JSON_UNLIKELY( num.bias + 1 == INT_MAX ))
2346   { 2346   {
2347   BOOST_STATIC_CONSTEXPR source_location loc 2347   BOOST_STATIC_CONSTEXPR source_location loc
2348   = BOOST_CURRENT_LOCATION; 2348   = BOOST_CURRENT_LOCATION;
HITCBC 2349   1 return fail(cs.begin(), error::exponent_overflow, &loc); 2349   1 return fail(cs.begin(), error::exponent_overflow, &loc);
2350   } 2350   }
HITCBC 2351   4294978560 ++cs; 2351   4294978560 ++cs;
HITCBC 2352   4294978560 ++num.bias; 2352   4294978560 ++num.bias;
2353   } 2353   }
HITCBC 2354   4139 else if(BOOST_JSON_LIKELY( 2354   4139 else if(BOOST_JSON_LIKELY(
2355   c == '.')) 2355   c == '.'))
2356   { 2356   {
HITCBC 2357   2028 ++cs; 2357   2028 ++cs;
HITCBC 2358   2028 break; 2358   2028 break;
2359   } 2359   }
HITCBC 2360   2111 else if((c | 32) == 'e') 2360   2111 else if((c | 32) == 'e')
2361   { 2361   {
HITCBC 2362   762 ++cs; 2362   762 ++cs;
HITCBC 2363   762 goto do_exp1; 2363   762 goto do_exp1;
2364   } 2364   }
2365   else 2365   else
2366   { 2366   {
HITCBC 2367   1349 goto finish_dub; 2367   1349 goto finish_dub;
2368   } 2368   }
2369   } 2369   }
2370   2370  
2371   //---------------------------------- 2371   //----------------------------------
2372   // 2372   //
2373   // DIGIT 2373   // DIGIT
2374   // first non-significant digit 2374   // first non-significant digit
2375   // to the right of decimal 2375   // to the right of decimal
2376   // 2376   //
HITCBC 2377   2080 do_num4: 2377   2080 do_num4:
2378   { 2378   {
HITCBC 2379   2080 if(BOOST_JSON_UNLIKELY(! cs)) 2379   2080 if(BOOST_JSON_UNLIKELY(! cs))
2380   { 2380   {
HITCBC 2381   64 if(BOOST_JSON_UNLIKELY( 2381   64 if(BOOST_JSON_UNLIKELY(
2382   ! h_.on_number_part( 2382   ! h_.on_number_part(
2383   {begin, cs.used(begin)}, ec_))) 2383   {begin, cs.used(begin)}, ec_)))
HITCBC 2384   6 return fail(cs.begin()); 2384   6 return fail(cs.begin());
2385   2385  
2386   BOOST_IF_CONSTEXPR( precise_parsing ) 2386   BOOST_IF_CONSTEXPR( precise_parsing )
MISUBC 2387   ✗ num_buf_.append( begin, cs.used(begin) ); 2387   ✗ num_buf_.append( begin, cs.used(begin) );
HITCBC 2388   52 return maybe_suspend( 2388   52 return maybe_suspend(
HITCBC 2389   52 cs.begin(), state::num4, num); 2389   52 cs.begin(), state::num4, num);
2390   } 2390   }
HITCBC 2391   2016 char const c = *cs; 2391   2016 char const c = *cs;
HITCBC 2392   2016 if(BOOST_JSON_LIKELY( 2392   2016 if(BOOST_JSON_LIKELY(
2393   //static_cast<unsigned char>(c - '0') < 10)) 2393   //static_cast<unsigned char>(c - '0') < 10))
2394   c >= '0' && c <= '9')) 2394   c >= '0' && c <= '9'))
2395   { 2395   {
HITCBC 2396   1949 ++cs; 2396   1949 ++cs;
2397   } 2397   }
2398   else 2398   else
2399   { 2399   {
2400   // digit required 2400   // digit required
2401   BOOST_STATIC_CONSTEXPR source_location loc 2401   BOOST_STATIC_CONSTEXPR source_location loc
2402   = BOOST_CURRENT_LOCATION; 2402   = BOOST_CURRENT_LOCATION;
HITCBC 2403   67 return fail(cs.begin(), error::syntax, &loc); 2403   67 return fail(cs.begin(), error::syntax, &loc);
2404   } 2404   }
2405   } 2405   }
2406   2406  
2407   //---------------------------------- 2407   //----------------------------------
2408   // 2408   //
2409   // 1*DIGIT 2409   // 1*DIGIT
2410   // non-significant digits 2410   // non-significant digits
2411   // to the right of decimal 2411   // to the right of decimal
2412   // 2412   //
HITCBC 2413   2013470 do_num5: 2413   2013470 do_num5:
HITCBC 2414   37889832 for(;;) 2414   37889832 for(;;)
2415   { 2415   {
HITCBC 2416   39903302 if(BOOST_JSON_UNLIKELY(! cs)) 2416   39903302 if(BOOST_JSON_UNLIKELY(! cs))
2417   { 2417   {
HITCBC 2418   6112 if(BOOST_JSON_UNLIKELY(more_)) 2418   6112 if(BOOST_JSON_UNLIKELY(more_))
2419   { 2419   {
HITCBC 2420   4577 if(BOOST_JSON_UNLIKELY( 2420   4577 if(BOOST_JSON_UNLIKELY(
2421   ! h_.on_number_part( 2421   ! h_.on_number_part(
2422   {begin, cs.used(begin)}, ec_))) 2422   {begin, cs.used(begin)}, ec_)))
HITCBC 2423   20 return fail(cs.begin()); 2423   20 return fail(cs.begin());
2424   2424  
2425   BOOST_IF_CONSTEXPR( precise_parsing ) 2425   BOOST_IF_CONSTEXPR( precise_parsing )
MISUBC 2426   ✗ num_buf_.append( begin, cs.used(begin) ); 2426   ✗ num_buf_.append( begin, cs.used(begin) );
HITCBC 2427   4537 return suspend(cs.begin(), state::num5, num); 2427   4537 return suspend(cs.begin(), state::num5, num);
2428   } 2428   }
HITCBC 2429   1535 goto finish_dub; 2429   1535 goto finish_dub;
2430   } 2430   }
HITCBC 2431   39897190 char const c = *cs; 2431   39897190 char const c = *cs;
HITCBC 2432   39897190 if(BOOST_JSON_LIKELY( 2432   39897190 if(BOOST_JSON_LIKELY(
2433   c >= '0' && c <= '9')) 2433   c >= '0' && c <= '9'))
2434   { 2434   {
HITCBC 2435   37889832 ++cs; 2435   37889832 ++cs;
2436   } 2436   }
HITCBC 2437   2007358 else if((c | 32) == 'e') 2437   2007358 else if((c | 32) == 'e')
2438   { 2438   {
HITCBC 2439   2003236 ++cs; 2439   2003236 ++cs;
HITCBC 2440   2003236 goto do_exp1; 2440   2003236 goto do_exp1;
2441   } 2441   }
2442   else 2442   else
2443   { 2443   {
HITCBC 2444   4122 goto finish_dub; 2444   4122 goto finish_dub;
2445   } 2445   }
2446   } 2446   }
2447   2447  
2448   //---------------------------------- 2448   //----------------------------------
2449   // 2449   //
2450   // [.eE] 2450   // [.eE]
2451   // 2451   //
HITCBC 2452   2055366 do_num6: 2452   2055366 do_num6:
2453   { 2453   {
HITCBC 2454   2055366 if(BOOST_JSON_UNLIKELY(! cs)) 2454   2055366 if(BOOST_JSON_UNLIKELY(! cs))
2455   { 2455   {
HITCBC 2456   800 if(BOOST_JSON_UNLIKELY(more_)) 2456   800 if(BOOST_JSON_UNLIKELY(more_))
2457   { 2457   {
HITCBC 2458   753 if(BOOST_JSON_UNLIKELY( 2458   753 if(BOOST_JSON_UNLIKELY(
2459   ! h_.on_number_part( 2459   ! h_.on_number_part(
2460   {begin, cs.used(begin)}, ec_))) 2460   {begin, cs.used(begin)}, ec_)))
HITCBC 2461   42 return fail(cs.begin()); 2461   42 return fail(cs.begin());
2462   2462  
2463   BOOST_IF_CONSTEXPR( precise_parsing ) 2463   BOOST_IF_CONSTEXPR( precise_parsing )
HITCBC 2464   2 num_buf_.append( begin, cs.used(begin) ); 2464   2 num_buf_.append( begin, cs.used(begin) );
HITCBC 2465   669 return suspend(cs.begin(), state::num6, num); 2465   669 return suspend(cs.begin(), state::num6, num);
2466   } 2466   }
HITCBC 2467   47 goto finish_int; 2467   47 goto finish_int;
2468   } 2468   }
HITCBC 2469   2054566 char const c = *cs; 2469   2054566 char const c = *cs;
HITCBC 2470   2054566 if(BOOST_JSON_LIKELY( 2470   2054566 if(BOOST_JSON_LIKELY(
2471   c == '.')) 2471   c == '.'))
2472   { 2472   {
HITCBC 2473   2016099 ++cs; 2473   2016099 ++cs;
2474   } 2474   }
HITCBC 2475   38467 else if((c | 32) == 'e') 2475   38467 else if((c | 32) == 'e')
2476   { 2476   {
HITCBC 2477   9153 ++cs; 2477   9153 ++cs;
HITCBC 2478   9153 goto do_exp1; 2478   9153 goto do_exp1;
2479   } 2479   }
2480   else 2480   else
2481   { 2481   {
HITCBC 2482   29314 goto finish_int; 2482   29314 goto finish_int;
2483   } 2483   }
2484   } 2484   }
2485   2485  
2486   //---------------------------------- 2486   //----------------------------------
2487   // 2487   //
2488   // DIGIT 2488   // DIGIT
2489   // first significant digit 2489   // first significant digit
2490   // to the right of decimal 2490   // to the right of decimal
2491   // 2491   //
HITCBC 2492   2016839 do_num7: 2492   2016839 do_num7:
2493   { 2493   {
HITCBC 2494   2016839 if(BOOST_JSON_UNLIKELY(! cs)) 2494   2016839 if(BOOST_JSON_UNLIKELY(! cs))
2495   { 2495   {
HITCBC 2496   693 if(BOOST_JSON_UNLIKELY(more_)) 2496   693 if(BOOST_JSON_UNLIKELY(more_))
2497   { 2497   {
HITCBC 2498   689 if(BOOST_JSON_UNLIKELY( 2498   689 if(BOOST_JSON_UNLIKELY(
2499   ! h_.on_number_part( 2499   ! h_.on_number_part(
2500   {begin, cs.used(begin)}, ec_))) 2500   {begin, cs.used(begin)}, ec_)))
HITCBC 2501   35 return fail(cs.begin()); 2501   35 return fail(cs.begin());
2502   2502  
2503   BOOST_IF_CONSTEXPR( precise_parsing ) 2503   BOOST_IF_CONSTEXPR( precise_parsing )
MISUBC 2504   ✗ num_buf_.append( begin, cs.used(begin) ); 2504   ✗ num_buf_.append( begin, cs.used(begin) );
HITCBC 2505   619 return suspend(cs.begin(), state::num7, num); 2505   619 return suspend(cs.begin(), state::num7, num);
2506   } 2506   }
2507   // digit required 2507   // digit required
2508   BOOST_STATIC_CONSTEXPR source_location loc 2508   BOOST_STATIC_CONSTEXPR source_location loc
2509   = BOOST_CURRENT_LOCATION; 2509   = BOOST_CURRENT_LOCATION;
HITCBC 2510   4 return fail(cs.begin(), error::syntax, &loc); 2510   4 return fail(cs.begin(), error::syntax, &loc);
2511   } 2511   }
HITCBC 2512   2016146 char const c = *cs; 2512   2016146 char const c = *cs;
HITCBC 2513   2016146 if(BOOST_JSON_UNLIKELY( 2513   2016146 if(BOOST_JSON_UNLIKELY(
2514   c < '0' || c > '9')) 2514   c < '0' || c > '9'))
2515   { 2515   {
2516   // digit required 2516   // digit required
2517   BOOST_STATIC_CONSTEXPR source_location loc 2517   BOOST_STATIC_CONSTEXPR source_location loc
2518   = BOOST_CURRENT_LOCATION; 2518   = BOOST_CURRENT_LOCATION;
HITCBC 2519   169 return fail(cs.begin(), error::syntax, &loc); 2519   169 return fail(cs.begin(), error::syntax, &loc);
2520   } 2520   }
2521   } 2521   }
2522   2522  
2523   //---------------------------------- 2523   //----------------------------------
2524   // 2524   //
2525   // 1*DIGIT 2525   // 1*DIGIT
2526   // significant digits 2526   // significant digits
2527   // to the right of decimal 2527   // to the right of decimal
2528   // 2528   //
HITCBC 2529   6228742 do_num8: 2529   6228742 do_num8:
HITCBC 2530   4298245220 for(;;) 2530   4298245220 for(;;)
2531   { 2531   {
HITCBC 2532   4304476462 if(BOOST_JSON_UNLIKELY(! cs)) 2532   4304476462 if(BOOST_JSON_UNLIKELY(! cs))
2533   { 2533   {
HITCBC 2534   4207120 if(BOOST_JSON_UNLIKELY(more_)) 2534   4207120 if(BOOST_JSON_UNLIKELY(more_))
2535   { 2535   {
HITCBC 2536   4205384 if(BOOST_JSON_UNLIKELY( 2536   4205384 if(BOOST_JSON_UNLIKELY(
2537   ! h_.on_number_part( 2537   ! h_.on_number_part(
2538   {begin, cs.used(begin)}, ec_))) 2538   {begin, cs.used(begin)}, ec_)))
HITCBC 2539   67 return fail(cs.begin()); 2539   67 return fail(cs.begin());
2540   2540  
2541   BOOST_IF_CONSTEXPR( precise_parsing ) 2541   BOOST_IF_CONSTEXPR( precise_parsing )
HITCBC 2542   2 num_buf_.append( begin, cs.used(begin) ); 2542   2 num_buf_.append( begin, cs.used(begin) );
HITCBC 2543   4205249 return suspend(cs.begin(), state::num8, num); 2543   4205249 return suspend(cs.begin(), state::num8, num);
2544   } 2544   }
HITCBC 2545   1736 goto finish_dub; 2545   1736 goto finish_dub;
2546   } 2546   }
HITCBC 2547   4300269342 char const c = *cs; 2547   4300269342 char const c = *cs;
HITCBC 2548   4300269342 if(BOOST_JSON_LIKELY( 2548   4300269342 if(BOOST_JSON_LIKELY(
2549   c >= '0' && c <= '9')) 2549   c >= '0' && c <= '9'))
2550   { 2550   {
HITCBC 2551   4300252205 ++cs; 2551   4300252205 ++cs;
HITCBC 2552   4300247112 if(!no_parsing && BOOST_JSON_LIKELY( 2552   4300247112 if(!no_parsing && BOOST_JSON_LIKELY(
2553   num.mant <= 9007199254740991)) // 2^53-1 2553   num.mant <= 9007199254740991)) // 2^53-1
2554   { 2554   {
HITCBC 2555   4298245221 if(BOOST_JSON_UNLIKELY( num.bias - 1 == INT_MIN )) 2555   4298245221 if(BOOST_JSON_UNLIKELY( num.bias - 1 == INT_MIN ))
2556   { 2556   {
2557   BOOST_STATIC_CONSTEXPR source_location loc 2557   BOOST_STATIC_CONSTEXPR source_location loc
2558   = BOOST_CURRENT_LOCATION; 2558   = BOOST_CURRENT_LOCATION;
HITCBC 2559   1 return fail(cs.begin(), error::exponent_overflow, &loc); 2559   1 return fail(cs.begin(), error::exponent_overflow, &loc);
2560   } 2560   }
HITCBC 2561   4298245220 --num.bias; 2561   4298245220 --num.bias;
HITCBC 2562   4298245220 num.mant = 10 * num.mant + ( c - '0' ); 2562   4298245220 num.mant = 10 * num.mant + ( c - '0' );
2563   } 2563   }
2564   else 2564   else
2565   { 2565   {
HITCBC 2566   2006984 goto do_num5; 2566   2006984 goto do_num5;
2567   } 2567   }
2568   } 2568   }
HITCBC 2569   17137 else if((c | 32) == 'e') 2569   17137 else if((c | 32) == 'e')
2570   { 2570   {
HITCBC 2571   11134 ++cs; 2571   11134 ++cs;
HITCBC 2572   11134 goto do_exp1; 2572   11134 goto do_exp1;
2573   } 2573   }
2574   else 2574   else
2575   { 2575   {
HITCBC 2576   6003 goto finish_dub; 2576   6003 goto finish_dub;
2577   } 2577   }
2578   } 2578   }
2579   2579  
2580   //---------------------------------- 2580   //----------------------------------
2581   // 2581   //
2582   // *[+-] 2582   // *[+-]
2583   // 2583   //
HITCBC 2584   2031448 do_exp1: 2584   2031448 do_exp1:
HITCBC 2585   2031448 if(BOOST_JSON_UNLIKELY(! cs)) 2585   2031448 if(BOOST_JSON_UNLIKELY(! cs))
2586   { 2586   {
HITCBC 2587   575 if(BOOST_JSON_UNLIKELY( 2587   575 if(BOOST_JSON_UNLIKELY(
2588   ! h_.on_number_part( 2588   ! h_.on_number_part(
2589   {begin, cs.used(begin)}, ec_))) 2589   {begin, cs.used(begin)}, ec_)))
HITCBC 2590   49 return fail(cs.begin()); 2590   49 return fail(cs.begin());
2591   2591  
2592   BOOST_IF_CONSTEXPR( precise_parsing ) 2592   BOOST_IF_CONSTEXPR( precise_parsing )
MISUBC 2593   ✗ num_buf_.append( begin, cs.used(begin) ); 2593   ✗ num_buf_.append( begin, cs.used(begin) );
HITCBC 2594   477 return maybe_suspend( 2594   477 return maybe_suspend(
HITCBC 2595   477 cs.begin(), state::exp1, num); 2595   477 cs.begin(), state::exp1, num);
2596   } 2596   }
HITCBC 2597   2030873 if(*cs == '+') 2597   2030873 if(*cs == '+')
2598   { 2598   {
HITCBC 2599   2364 ++cs; 2599   2364 ++cs;
2600   } 2600   }
HITCBC 2601   2028509 else if(*cs == '-') 2601   2028509 else if(*cs == '-')
2602   { 2602   {
HITCBC 2603   1001936 ++cs; 2603   1001936 ++cs;
HITCBC 2604   1001936 num.frac = true; 2604   1001936 num.frac = true;
2605   } 2605   }
2606   2606  
2607   //---------------------------------- 2607   //----------------------------------
2608   // 2608   //
2609   // DIGIT 2609   // DIGIT
2610   // first digit of the exponent 2610   // first digit of the exponent
2611   // 2611   //
HITCBC 2612   1026573 do_exp2: 2612   1026573 do_exp2:
2613   { 2613   {
HITCBC 2614   2031012 if(BOOST_JSON_UNLIKELY(! cs)) 2614   2031012 if(BOOST_JSON_UNLIKELY(! cs))
2615   { 2615   {
HITCBC 2616   188 if(BOOST_JSON_UNLIKELY(more_)) 2616   188 if(BOOST_JSON_UNLIKELY(more_))
2617   { 2617   {
HITCBC 2618   179 if(BOOST_JSON_UNLIKELY( 2618   179 if(BOOST_JSON_UNLIKELY(
2619   ! h_.on_number_part( 2619   ! h_.on_number_part(
2620   {begin, cs.used(begin)}, ec_))) 2620   {begin, cs.used(begin)}, ec_)))
HITCBC 2621   20 return fail(cs.begin()); 2621   20 return fail(cs.begin());
2622   2622  
2623   BOOST_IF_CONSTEXPR( precise_parsing ) 2623   BOOST_IF_CONSTEXPR( precise_parsing )
MISUBC 2624   ✗ num_buf_.append( begin, cs.used(begin) ); 2624   ✗ num_buf_.append( begin, cs.used(begin) );
HITCBC 2625   139 return suspend(cs.begin(), state::exp2, num); 2625   139 return suspend(cs.begin(), state::exp2, num);
2626   } 2626   }
2627   // digit required 2627   // digit required
2628   BOOST_STATIC_CONSTEXPR source_location loc 2628   BOOST_STATIC_CONSTEXPR source_location loc
2629   = BOOST_CURRENT_LOCATION; 2629   = BOOST_CURRENT_LOCATION;
HITCBC 2630   9 return fail(cs.begin(), error::syntax, &loc); 2630   9 return fail(cs.begin(), error::syntax, &loc);
2631   } 2631   }
HITCBC 2632   2030824 char const c = *cs; 2632   2030824 char const c = *cs;
HITCBC 2633   2030824 if(BOOST_JSON_UNLIKELY( 2633   2030824 if(BOOST_JSON_UNLIKELY(
2634   c < '0' || c > '9')) 2634   c < '0' || c > '9'))
2635   { 2635   {
2636   // digit required 2636   // digit required
2637   BOOST_STATIC_CONSTEXPR source_location loc 2637   BOOST_STATIC_CONSTEXPR source_location loc
2638   = BOOST_CURRENT_LOCATION; 2638   = BOOST_CURRENT_LOCATION;
HITCBC 2639   508 return fail(cs.begin(), error::syntax, &loc); 2639   508 return fail(cs.begin(), error::syntax, &loc);
2640   } 2640   }
HITCBC 2641   2030316 ++cs; 2641   2030316 ++cs;
HITCBC 2642   2030316 num.exp = c - '0'; 2642   2030316 num.exp = c - '0';
2643   } 2643   }
2644   2644  
2645   //---------------------------------- 2645   //----------------------------------
2646   // 2646   //
2647   // 1*DIGIT 2647   // 1*DIGIT
2648   // subsequent digits in the exponent 2648   // subsequent digits in the exponent
2649   // 2649   //
HITCBC 2650   2042421 do_exp3: 2650   2042421 do_exp3:
HITCBC 2651   5468163 for(;;) 2651   5468163 for(;;)
2652   { 2652   {
HITCBC 2653   7510584 if(BOOST_JSON_UNLIKELY(! cs)) 2653   7510584 if(BOOST_JSON_UNLIKELY(! cs))
2654   { 2654   {
HITCBC 2655   2020838 if(BOOST_JSON_UNLIKELY(more_)) 2655   2020838 if(BOOST_JSON_UNLIKELY(more_))
2656   { 2656   {
HITCBC 2657   12277 if(BOOST_JSON_UNLIKELY( 2657   12277 if(BOOST_JSON_UNLIKELY(
2658   ! h_.on_number_part( 2658   ! h_.on_number_part(
2659   {begin, cs.used(begin)}, ec_))) 2659   {begin, cs.used(begin)}, ec_)))
HITCBC 2660   86 return fail(cs.begin()); 2660   86 return fail(cs.begin());
2661   2661  
2662   BOOST_IF_CONSTEXPR( precise_parsing ) 2662   BOOST_IF_CONSTEXPR( precise_parsing )
MISUBC 2663   ✗ num_buf_.append( begin, cs.used(begin) ); 2663   ✗ num_buf_.append( begin, cs.used(begin) );
HITCBC 2664   12105 return suspend(cs.begin(), state::exp3, num); 2664   12105 return suspend(cs.begin(), state::exp3, num);
2665   } 2665   }
2666   } 2666   }
2667   else 2667   else
2668   { 2668   {
HITCBC 2669   5489746 char const c = *cs; 2669   5489746 char const c = *cs;
HITCBC 2670   5489746 if(BOOST_JSON_LIKELY( c >= '0' && c <= '9' )) 2670   5489746 if(BOOST_JSON_LIKELY( c >= '0' && c <= '9' ))
2671   { 2671   {
HITCBC 2672   5468163 if(BOOST_JSON_UNLIKELY( 2672   5468163 if(BOOST_JSON_UNLIKELY(
2673   // 2147483647 INT_MAX 2673   // 2147483647 INT_MAX
2674   num.exp > 214748364 || 2674   num.exp > 214748364 ||
2675   (num.exp == 214748364 && c > '7') 2675   (num.exp == 214748364 && c > '7')
2676   )) 2676   ))
HITCBC 2677   3855 num.exp = INT_MAX; 2677   3855 num.exp = INT_MAX;
2678   else BOOST_IF_CONSTEXPR( !no_parsing ) 2678   else BOOST_IF_CONSTEXPR( !no_parsing )
HITCBC 2679   4923456 num.exp = 10 * num.exp + ( c - '0' ); 2679   4923456 num.exp = 10 * num.exp + ( c - '0' );
2680   2680  
HITCBC 2681   5468163 ++cs; 2681   5468163 ++cs;
HITCBC 2682   5468163 continue; 2682   5468163 continue;
2683   } 2683   }
2684   } 2684   }
HITCBC 2685   2030144 BOOST_ASSERT(num.exp >= 0); 2685   2030144 BOOST_ASSERT(num.exp >= 0);
HITCBC 2686   2030144 if ( num.frac ) 2686   2030144 if ( num.frac )
2687   { 2687   {
HITCBC 2688   1001800 if(BOOST_JSON_UNLIKELY( num.bias < (INT_MIN + num.exp) )) 2688   1001800 if(BOOST_JSON_UNLIKELY( num.bias < (INT_MIN + num.exp) ))
2689   { 2689   {
2690   // if exponent overflowed, bias is a very large negative 2690   // if exponent overflowed, bias is a very large negative
2691   // number, and mantissa isn't zero, then we cannot parse the 2691   // number, and mantissa isn't zero, then we cannot parse the
2692   // number correctly 2692   // number correctly
HITCBC 2693   92 if(BOOST_JSON_UNLIKELY( 2693   92 if(BOOST_JSON_UNLIKELY(
2694   (num.exp == INT_MAX) && 2694   (num.exp == INT_MAX) &&
2695   (num.bias < 0) && 2695   (num.bias < 0) &&
2696   (num.exp + num.bias < 308) && 2696   (num.exp + num.bias < 308) &&
2697   num.mant )) 2697   num.mant ))
2698   { 2698   {
2699   BOOST_STATIC_CONSTEXPR source_location loc 2699   BOOST_STATIC_CONSTEXPR source_location loc
2700   = BOOST_CURRENT_LOCATION; 2700   = BOOST_CURRENT_LOCATION;
HITCBC 2701   1 return fail(cs.begin(), error::exponent_overflow, &loc); 2701   1 return fail(cs.begin(), error::exponent_overflow, &loc);
2702   } 2702   }
2703   2703  
HITCBC 2704   91 num.bias = 0; 2704   91 num.bias = 0;
HITCBC 2705   91 num.exp = INT_MAX; 2705   91 num.exp = INT_MAX;
2706   } 2706   }
2707   } 2707   }
HITCBC 2708   1028344 else if (BOOST_JSON_UNLIKELY( num.bias > (INT_MAX - num.exp) )) 2708   1028344 else if (BOOST_JSON_UNLIKELY( num.bias > (INT_MAX - num.exp) ))
2709   { 2709   {
2710   // if exponent overflowed, bias is a very large positive number, 2710   // if exponent overflowed, bias is a very large positive number,
2711   // and mantissa isn't zero, then we cannot parse the 2711   // and mantissa isn't zero, then we cannot parse the
2712   // number correctly 2712   // number correctly
HITCBC 2713   194 if(BOOST_JSON_UNLIKELY( 2713   194 if(BOOST_JSON_UNLIKELY(
2714   (num.exp == INT_MAX) && 2714   (num.exp == INT_MAX) &&
2715   (num.bias > 0) && 2715   (num.bias > 0) &&
2716   (num.exp - num.bias < 308) && 2716   (num.exp - num.bias < 308) &&
2717   num.mant )) 2717   num.mant ))
2718   { 2718   {
2719   BOOST_STATIC_CONSTEXPR source_location loc 2719   BOOST_STATIC_CONSTEXPR source_location loc
2720   = BOOST_CURRENT_LOCATION; 2720   = BOOST_CURRENT_LOCATION;
HITCBC 2721   1 return fail(cs.begin(), error::exponent_overflow, &loc); 2721   1 return fail(cs.begin(), error::exponent_overflow, &loc);
2722   } 2722   }
2723   2723  
HITCBC 2724   193 num.bias = 0; 2724   193 num.bias = 0;
HITCBC 2725   193 num.exp = INT_MAX; 2725   193 num.exp = INT_MAX;
2726   } 2726   }
HITCBC 2727   2030142 goto finish_dub; 2727   2030142 goto finish_dub;
2728   } 2728   }
2729   2729  
HITCBC 2730   30426 finish_int: 2730   30426 finish_int:
HITCBC 2731   28497 if(negative || (!stack_empty && num.neg)) 2731   28497 if(negative || (!stack_empty && num.neg))
2732   { 2732   {
HITCBC 2733   2531 if(BOOST_JSON_UNLIKELY( 2733   2531 if(BOOST_JSON_UNLIKELY(
2734   ! h_.on_int64(static_cast< 2734   ! h_.on_int64(static_cast<
2735   int64_t>(~num.mant + 1), {begin, cs.used(begin)}, ec_))) 2735   int64_t>(~num.mant + 1), {begin, cs.used(begin)}, ec_)))
HITCBC 2736   310 return fail(cs.begin()); 2736   310 return fail(cs.begin());
HITCBC 2737   1913 return cs.begin(); 2737   1913 return cs.begin();
2738   } 2738   }
HITCBC 2739   27895 if(num.mant <= INT64_MAX) 2739   27895 if(num.mant <= INT64_MAX)
2740   { 2740   {
HITCBC 2741   27594 finish_signed: 2741   27594 finish_signed:
HITCBC 2742   30869 if(BOOST_JSON_UNLIKELY( 2742   30869 if(BOOST_JSON_UNLIKELY(
2743   ! h_.on_int64(static_cast< 2743   ! h_.on_int64(static_cast<
2744   int64_t>(num.mant), {begin, cs.used(begin)}, ec_))) 2744   int64_t>(num.mant), {begin, cs.used(begin)}, ec_)))
HITCBC 2745   2267 return fail(cs.begin()); 2745   2267 return fail(cs.begin());
HITCBC 2746   26342 return cs.begin(); 2746   26342 return cs.begin();
2747   } 2747   }
HITCBC 2748   321 if(BOOST_JSON_UNLIKELY( 2748   321 if(BOOST_JSON_UNLIKELY(
2749   ! h_.on_uint64(num.mant, {begin, cs.used(begin)}, ec_))) 2749   ! h_.on_uint64(num.mant, {begin, cs.used(begin)}, ec_)))
HITCBC 2750   35 return fail(cs.begin()); 2750   35 return fail(cs.begin());
HITCBC 2751   254 return cs.begin(); 2751   254 return cs.begin();
HITCBC 2752   2052467 finish_dub: 2752   2052467 finish_dub:
2753   double d; 2753   double d;
HITCBC 2754   2052467 std::size_t const size = cs.used(begin); 2754   2052467 std::size_t const size = cs.used(begin);
HITCBC 2755   2052467 BOOST_ASSERT( !num_buf_.size() || precise_parsing ); 2755   2052467 BOOST_ASSERT( !num_buf_.size() || precise_parsing );
2756   BOOST_IF_CONSTEXPR( precise_parsing ) 2756   BOOST_IF_CONSTEXPR( precise_parsing )
2757   { 2757   {
HITCBC 2758   1000052 char const* data = begin; 2758   1000052 char const* data = begin;
HITCBC 2759   1000052 std::size_t full_size = size; 2759   1000052 std::size_t full_size = size;
2760   // if we previously suspended or if the current input ends with the 2760   // if we previously suspended or if the current input ends with the
2761   // number, we need to copy the current part of the number to the 2761   // number, we need to copy the current part of the number to the
2762   // temporary buffer 2762   // temporary buffer
HITCBC 2763   1000052 if(BOOST_JSON_UNLIKELY( num_buf_.size() )) 2763   1000052 if(BOOST_JSON_UNLIKELY( num_buf_.size() ))
2764   { 2764   {
HITCBC 2765   1 data = num_buf_.append( begin, size ); 2765   1 data = num_buf_.append( begin, size );
HITCBC 2766   1 full_size = num_buf_.size(); 2766   1 full_size = num_buf_.size();
2767   } 2767   }
HITCBC 2768   1000052 auto const err = detail::charconv::from_chars( 2768   1000052 auto const err = detail::charconv::from_chars(
2769   data, data + full_size, d ); 2769   data, data + full_size, d );
HITCBC 2770   1000052 BOOST_ASSERT( err.ec != std::errc::invalid_argument ); 2770   1000052 BOOST_ASSERT( err.ec != std::errc::invalid_argument );
HITCBC 2771   1000052 BOOST_ASSERT( err.ptr == data + full_size ); 2771   1000052 BOOST_ASSERT( err.ptr == data + full_size );
2772   (void)err; 2772   (void)err;
2773   } 2773   }
2774   else BOOST_IF_CONSTEXPR( no_parsing ) 2774   else BOOST_IF_CONSTEXPR( no_parsing )
HITCBC 2775   9258 d = 0; 2775   9258 d = 0;
2776   else 2776   else
HITCBC 2777   1043157 d = detail::dec_to_float( 2777   1043157 d = detail::dec_to_float(
2778   num.mant, 2778   num.mant,
HITCBC 2779   541045 num.bias + (num.frac ? 2779   541045 num.bias + (num.frac ?
HITCBC 2780   502112 -num.exp : num.exp), 2780   502112 -num.exp : num.exp),
HITCBC 2781   1043157 num.neg); 2781   1043157 num.neg);
HITCBC 2782   2052467 if(BOOST_JSON_UNLIKELY( 2782   2052467 if(BOOST_JSON_UNLIKELY(
2783   ! h_.on_double(d, {begin, size}, ec_))) 2783   ! h_.on_double(d, {begin, size}, ec_)))
HITCBC 2784   1935 return fail(cs.begin()); 2784   1935 return fail(cs.begin());
HITCBC 2785   2048597 return cs.begin(); 2785   2048597 return cs.begin();
2786   } 2786   }
2787   2787  
2788   //---------------------------------------------------------- 2788   //----------------------------------------------------------
2789   2789  
2790   template<class Handler> 2790   template<class Handler>
2791   template<class... Args> 2791   template<class... Args>
HITCBC 2792   2165003 basic_parser<Handler>:: 2792   2165003 basic_parser<Handler>::
2793   basic_parser( 2793   basic_parser(
2794   parse_options const& opt, 2794   parse_options const& opt,
2795   Args&&... args) 2795   Args&&... args)
HITCBC 2796   2164994 : h_(std::forward<Args>(args)...) 2796   2164994 : h_(std::forward<Args>(args)...)
HITCBC 2797   2165003 , opt_(opt) 2797   2165003 , opt_(opt)
2798   { 2798   {
HITCBC 2799   2165003 } 2799   2165003 }
2800   2800  
2801   //---------------------------------------------------------- 2801   //----------------------------------------------------------
2802   2802  
2803   template<class Handler> 2803   template<class Handler>
2804   void 2804   void
HITCBC 2805   4153166 basic_parser<Handler>:: 2805   4153166 basic_parser<Handler>::
2806   reset() noexcept 2806   reset() noexcept
2807   { 2807   {
HITCBC 2808   4153166 ec_ = {}; 2808   4153166 ec_ = {};
HITCBC 2809   4153166 st_.clear(); 2809   4153166 st_.clear();
HITCBC 2810   4153166 more_ = true; 2810   4153166 more_ = true;
HITCBC 2811   4153166 done_ = false; 2811   4153166 done_ = false;
HITCBC 2812   4153166 clean_ = true; 2812   4153166 clean_ = true;
HITCBC 2813   4153166 num_buf_.clear(); 2813   4153166 num_buf_.clear();
HITCBC 2814   4153166 } 2814   4153166 }
2815   2815  
2816   template<class Handler> 2816   template<class Handler>
2817   void 2817   void
HITCBC 2818   18 basic_parser<Handler>:: 2818   18 basic_parser<Handler>::
2819   fail(system::error_code ec) noexcept 2819   fail(system::error_code ec) noexcept
2820   { 2820   {
HITCBC 2821   18 if(! ec) 2821   18 if(! ec)
2822   { 2822   {
2823   // assign an arbitrary 2823   // assign an arbitrary
2824   // error code to prevent UB 2824   // error code to prevent UB
HITCBC 2825   1 BOOST_JSON_FAIL(ec_, error::incomplete); 2825   1 BOOST_JSON_FAIL(ec_, error::incomplete);
2826   } 2826   }
2827   else 2827   else
2828   { 2828   {
HITCBC 2829   17 ec_ = ec; 2829   17 ec_ = ec;
2830   } 2830   }
HITCBC 2831   18 done_ = false; 2831   18 done_ = false;
HITCBC 2832   18 } 2832   18 }
2833   2833  
2834   //---------------------------------------------------------- 2834   //----------------------------------------------------------
2835   2835  
2836   template<class Handler> 2836   template<class Handler>
2837   std::size_t 2837   std::size_t
HITCBC 2838   10726546 basic_parser<Handler>:: 2838   10726546 basic_parser<Handler>::
2839   write_some( 2839   write_some(
2840   bool more, 2840   bool more,
2841   char const* data, 2841   char const* data,
2842   std::size_t size, 2842   std::size_t size,
2843   system::error_code& ec) 2843   system::error_code& ec)
2844   { 2844   {
2845   // see if we exited via exception 2845   // see if we exited via exception
2846   // on the last call to write_some 2846   // on the last call to write_some
HITCBC 2847   10726546 if(! clean_) 2847   10726546 if(! clean_)
2848   { 2848   {
2849   // prevent UB 2849   // prevent UB
HITCBC 2850   1 if(! ec_) 2850   1 if(! ec_)
2851   { 2851   {
HITCBC 2852   1 BOOST_JSON_FAIL(ec_, error::exception); 2852   1 BOOST_JSON_FAIL(ec_, error::exception);
2853   } 2853   }
2854   } 2854   }
HITCBC 2855   10726546 if(ec_) 2855   10726546 if(ec_)
2856   { 2856   {
2857   // error is sticky 2857   // error is sticky
HITCBC 2858   5 ec = ec_; 2858   5 ec = ec_;
HITCBC 2859   5 return 0; 2859   5 return 0;
2860   } 2860   }
HITCBC 2861   10726541 clean_ = false; 2861   10726541 clean_ = false;
HITCBC 2862   10726541 more_ = more; 2862   10726541 more_ = more;
HITCBC 2863   10726541 end_ = data + size; 2863   10726541 end_ = data + size;
2864   const char* p; 2864   const char* p;
HITCBC 2865   10726541 if(BOOST_JSON_LIKELY(st_.empty())) 2865   10726541 if(BOOST_JSON_LIKELY(st_.empty()))
2866   { 2866   {
2867   // first time 2867   // first time
HITCBC 2868   2164992 depth_ = opt_.max_depth; 2868   2164992 depth_ = opt_.max_depth;
HITCBC 2869   2164992 if(BOOST_JSON_UNLIKELY( 2869   2164992 if(BOOST_JSON_UNLIKELY(
2870   ! h_.on_document_begin(ec_))) 2870   ! h_.on_document_begin(ec_)))
2871   { 2871   {
HITCBC 2872   7928 ec = ec_; 2872   7928 ec = ec_;
HITCBC 2873   7928 return 0; 2873   7928 return 0;
2874   } 2874   }
HITCBC 2875   2149135 p = parse_document(data, std::true_type()); 2875   2149135 p = parse_document(data, std::true_type());
2876   } 2876   }
2877   else 2877   else
2878   { 2878   {
HITCBC 2879   8561549 p = parse_document(data, std::false_type()); 2879   8561549 p = parse_document(data, std::false_type());
2880   } 2880   }
2881   2881  
HITCBC 2882   10691516 if(BOOST_JSON_LIKELY(p != sentinel())) 2882   10691516 if(BOOST_JSON_LIKELY(p != sentinel()))
2883   { 2883   {
HITCBC 2884   2099209 BOOST_ASSERT(! ec_); 2884   2099209 BOOST_ASSERT(! ec_);
HITCBC 2885   2099209 if(! done_) 2885   2099209 if(! done_)
2886   { 2886   {
HITCBC 2887   2031786 done_ = true; 2887   2031786 done_ = true;
HITCBC 2888   2031786 h_.on_document_end(ec_); 2888   2031786 h_.on_document_end(ec_);
2889   } 2889   }
2890   } 2890   }
2891   else 2891   else
2892   { 2892   {
HITCBC 2893   8592307 if(! ec_) 2893   8592307 if(! ec_)
2894   { 2894   {
HITCBC 2895   8565450 if(! more_) 2895   8565450 if(! more_)
2896   { 2896   {
HITCBC 2897   589 BOOST_JSON_FAIL(ec_, error::incomplete); 2897   589 BOOST_JSON_FAIL(ec_, error::incomplete);
2898   } 2898   }
HITCBC 2899   8564861 else if(! st_.empty()) 2899   8564861 else if(! st_.empty())
2900   { 2900   {
2901   // consume as much trailing whitespace in 2901   // consume as much trailing whitespace in
2902   // the JSON document as possible, but still 2902   // the JSON document as possible, but still
2903   // consider the parse complete 2903   // consider the parse complete
2904   state st; 2904   state st;
HITCBC 2905   8564861 st_.peek(st); 2905   8564861 st_.peek(st);
HITCBC 2906   8564861 if( st == state::doc3 && 2906   8564861 if( st == state::doc3 &&
HITCBC 2907   88559 ! done_) 2907   88559 ! done_)
2908   { 2908   {
HITCBC 2909   70732 done_ = true; 2909   70732 done_ = true;
HITCBC 2910   70732 h_.on_document_end(ec_); 2910   70732 h_.on_document_end(ec_);
2911   } 2911   }
2912   } 2912   }
2913   } 2913   }
HITCBC 2914   8590663 p = end_; 2914   8590663 p = end_;
2915   } 2915   }
HITCBC 2916   10685880 ec = ec_; 2916   10685880 ec = ec_;
HITCBC 2917   10685880 clean_ = true; 2917   10685880 clean_ = true;
HITCBC 2918   10685880 return p - data; 2918   10685880 return p - data;
2919   } 2919   }
2920   2920  
2921   template<class Handler> 2921   template<class Handler>
2922   std::size_t 2922   std::size_t
HITCBC 2923   1 basic_parser<Handler>:: 2923   1 basic_parser<Handler>::
2924   write_some( 2924   write_some(
2925   bool more, 2925   bool more,
2926   char const* data, 2926   char const* data,
2927   std::size_t size, 2927   std::size_t size,
2928   std::error_code& ec) 2928   std::error_code& ec)
2929   { 2929   {
HITCBC 2930   1 system::error_code jec; 2930   1 system::error_code jec;
HITCBC 2931   1 std::size_t const result = write_some(more, data, size, jec); 2931   1 std::size_t const result = write_some(more, data, size, jec);
HITCBC 2932   1 ec = jec; 2932   1 ec = jec;
HITCBC 2933   1 return result; 2933   1 return result;
2934   } 2934   }
2935   2935  
2936   #endif 2936   #endif
2937   2937  
2938   } // namespace json 2938   } // namespace json
2939   } // namespace boost 2939   } // namespace boost
2940   2940  
2941   #ifdef _MSC_VER 2941   #ifdef _MSC_VER
2942   #pragma warning(pop) 2942   #pragma warning(pop)
2943   #endif 2943   #endif
2944   2944  
2945   #endif 2945   #endif